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

来源:互联网 发布:穿帮镜头软件 编辑:程序博客网 时间:2024/06/05 01:56
//**********************位图***********************

//腾讯面试题:
//           给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>
usingnamespacestd;

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

                //把某个数对应的比特位标记为1表示这个数存在
                boolSet(size_tdata)
                {
                                //找data对应的比特位
                                size_tindex =data>> 5;     
                                size_tnum =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;                      
                                                returntrue;
                                }
                                else
                                {
                                                returnfalse;
                                }
                }

                boolReset(size_tdata)
                {
                                //找data对应的比特位
                                size_tindex =data>> 5;
                                size_tnum =data% 32;

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

                boolTest(size_tdata)
                {
                                //找数据对应的比特位
                                size_tindex =data>> 5;
                                size_tnum =data% 32;

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

                size_tSize()
                {
                                returnsize;
                }
private:
                vector<size_t> arr;
                size_tsize;
};


voidTestBitMap()
{
                BitMapbt(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
}

intmain()
{
                TestBitMap();
                return0;

}







0 0