#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;
}
从42亿个不重复的4字节整数中判断一个数是否存在
最新推荐文章于 2023-11-23 22:43:00 发布