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

如果常规的想法是给这40亿数,放到一个很大的数组中,快速排序,然后采用二分查找,来判断这个数是否存在;
但是计算机的内存就是4G,大小差不多刚好是2^32大约为42亿左右,一个整形4个字节,40亿数大约需要16G个字节,在现实基本不可能实现,那么该如何存储呢?
方法:位存储
一个整形32个位,16G个字节只需要500M就可以,然后设置比特位1表示这个数存在,0表示这个数不存在。

#include<vector>
using namespace std;
class BitSet
{
public:
    BitSet(size_t range)
    {
        _a.resize((range >>5)+ 1);
    }
  //位置(置1)
    void Set(int num)
    {
        size_t index = num >>5;//确定是第几个整数
        size_t pos = num % 32;//确定在那个位

        _a[index] |= (1<< pos);//置1
    }
    //位置清0(置0)
    void ReSet(int num)
    {
        size_t index = num >> 5;//确定是第几个整数
        size_t pos = num % 32;//确定在那个位
        //表示该位置的数不存在
        _a[index] &= ~(1 << pos);//置0
    }
    //判断是否存在
    bool Test(int num)
    {
        size_t index = num >> 5;//算整数
        size_t  pos = num % 32;//算位置
        //为1表示存在,为0表示不存在
        return _a[index] &= (1 << pos);
    }
protected:
    vector<int>_a;
};
void Test()
{
    BitSet bs(-1);
    bs.Set(1);
    bs.Set(8);
    bs.Set(100);
    cout << "bs?" << "bs.Set(1) " << endl;
    cout << "bs?" << "bs.Set(8) " << endl;
    cout << "bs?" << "bs.Set(100) " << endl;
    cout << "bs?" << "bs.Test(1) " << endl;
    cout << "bs?" << "bs.Test(1) " << endl;
    cout << "bs?" << "bs.Test(1) " << endl;
}

这里写图片描述
那么如何给一个数置1还是清0呢?
这里写图片描述
我们知道-1在计算机是按照补码的方式存储,为全1;11111111 11111111 11111111 11111111,转换成无符号的整形就是2^32-1,这样就可以存储整形里面所有的数字了。
加强版:
给定一个100亿的数,设计算法找到只出现一次的整数;
这个也是一个大数存储的问题,和前面一样按照常规的存储内存肯定放不下,但是如果按照位图的方式存储,大约需要1.25G的内存计算机可以容纳.
但是此时的状态有三种:
a:不存在
b:出现一次
c:出现多次
如果有一个位的话只能表示2种状态,为了解决这个问题我们可以用2个位来表示状态,这样就可以表示多种状态,0表示不存在,1表示出现一次,2或者3表示出现多次,这样就可以快速判断只出现一次的整数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值