从42亿个不重复的4字节整数中判断一个数是否存在


#include <math.h>
#include <stdio.h>

//位图法,用位来表示状态

/*
如何在42亿个不重复的4字节类型的整数中确认一个数是否存在?
如果将所有的数字存放在int类型的数组中,然后一个一个比较,那么需要4294967295*4/1024/1024/1024=15G内存才可以存放下所有的数
并且速度会是非常慢的,那么可以采用分布式计算,将所有数据分步在多台计算机中,处理完将结果合并,这样速度会快一点。
最好的方法就是位图法进行查找数据

位图法查找原理就是:
因为有42亿个int类型整数并且不重复,所以可以用42亿个位来表示是存在还是不存在(0/1两个状态)
数字大小是多少,就在对应的位上用0/1表示存在或者不存在,比较时候只需要取出这个数字对应的位的值是0或者1就可以知道是否存在
这种方法的巧妙之处就是使用位数组来存放状态,下标就是数字大小,数字的值就是表示状态,因为是位数组,所以即使是42亿个数字,也只需要
42/8/1024/1024 = 511M大小
该方法只有第一次初始化位状态的时候比较费时间,但是之后查找时候可以直接确定是否存在


*/

unsigned char existNum[536870911];    //使用字节数字,那么存放42亿个数的状态是需要4294967295/8 = 536870911字节大小

void InitNum(unsigned int testArr[], int len)
{
    //将待查找数组放入使用位表示的数组中
    for (unsigned int i = 0; i < len; i++)
    {
        //初始化数字对应的位的状态
        unsigned int index = testArr[i] / 8;
        int indexBit = (testArr[i] % 8);
        existNum[index] ^= (int)pow(2, indexBit);
    }
}
bool FindNum(unsigned int value)
{
    unsigned int index = value / 8;
    int indexBit = (value % 8);
    return existNum[index] & (int)pow(2, indexBit);
}

int main()
{
    unsigned int testArr[] = { 100,99999,2123123,123124,234,2345,346,4567,345345234,356456 };
    InitNum(testArr, sizeof(testArr) / 4);
    bool ret = FindNum(999929);

    printf("%s\n", ret ? "true":"false");
    getchar();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值