面试题:给40亿个不重复的无符号整数,没排过序,给一个无符号整数如何快速判断这个数是否在这40亿个数中

//**********************位图***********************

//腾讯面试题:
//           给40亿个不重复的无符号整数,没排过序,给一个无符号整数如何
//           快速判断这个数是否在这40亿个数中

//解题思路:
//(1)直接存进内存
//40亿个无符号数,如果放到内存,就需要开辟4*4G=16G的空间,因为数的范围不确定,所以
//开辟尽可能大的空间来存放,需42亿9千万×4字节的空间
//(2)位图   
//位图:在一块内存区域的每个比特存0或1,表示其对应的元素不存在或者存在
//位图优点: 速度快,内存空间占用小,能表示大范围的数据

//比较:用位图的话,需(42亿9千万×4字节)/32字节=大约500M的空间内存就可以
//      把40亿个数全部放进内存

//按位与&:都为真时才为真,即都为1时才为1
//按位或|:都为假时才为假,即都为0时才为0
//按位异或^:两个数不同时为1
//左移<<是往高位移     如在一个从0到31的比特位中,让1<<2,则比特位变为00100000  00000000   00000000  00000000
//右移>>是往低位移   x>>1等于x/2   x>>5等于x/32

#include <iostream>
#include <vector>
using namespace std;

class BitMap
{
public :
                BitMap( size_t range )
                                :size(0)
                {
                                arr.resize(( range >> 5) + 1);
                }

                 //把某个数对应的比特位标记为1表示这个数存在
                 bool Set( size_t data )
                {
                                 //找data对应的比特位
                                 size_t index = data >> 5;     
                                 size_t num = data % 32;

                                 //arr是vector类型的,会被自动初始化为0
                                 //1<<num时只有一位为1,其余都为0,当数据对应的比特位为0时进入循环,防止对一个数据进行多次标记,使size和实际数据不符
                                 if (!(arr[index] & (1 << num)))     
                                {
                                                arr[index] |= (1 << num);      //arr中的值与(1 << num)保证了已经被标记为1的地方不变
                                                ++size;                      
                                                 return true ;
                                }
                                 else
                                {
                                                 return false ;
                                }
                }

                 bool Reset( size_t data )
                {
                                 //找data对应的比特位
                                 size_t index = data >> 5;
                                 size_t num = data % 32;

                                 //当数据对应的比特位为1时进入循环,防止多次Reset,size在一个数上面多次--
                                 if (arr[index] & (1 << num))    
                                {
                                                arr[index] &= (~(1 << num));   
                                                --size;
                                                 return true ;
                                }
                                 else
                                {
                                                 return false ;
                                }
                }

                 bool Test( size_t data )
                {
                                 //找数据对应的比特位
                                 size_t index = data >> 5;
                                 size_t num = data % 32;

                                 //结果为1则存在,结果为0则不存在
                                 return arr[index] & (1 << num);  
                }

                 size_t Size()
                {
                                 return size;
                }
private :
                 vector < size_t > arr;
                 size_t size;
};


void TestBitMap()
{
                 BitMap bt(10);
                bt.Set(9);
                bt.Set(5);

                cout << "9是否存在?" << bt.Test(9) << endl;    //1
                cout << "6是否存在?" << bt.Test(6) << endl;    //0

                 //bt.Reset(9);
                 //cout <<"9是否存在?"<< bt.Test(9) << endl;

                bt.Set(7);
                bt.Set(7);
                bt.Set(7);
                cout << "7是否存在?" << bt.Test(7) << endl;   //1
                cout << "size=" << bt.Size() << endl;          //3

                bt.Reset(7);
                bt.Reset(7);
                bt.Reset(7);
                cout << "7是否存在?" << bt.Test(7) << endl;   //0
                cout << "size=" << bt.Size() << endl;          //2
}

int main()
{
                TestBitMap();
                 return 0;

}


面试题:给40亿个不重复的无符号整数,没排过序,给一个无符号整数如何快速判断这个数是否在这40亿个数中_第1张图片





你可能感兴趣的:(数据结构,位图)