C++进阶哈希的应用
Posted Huang_ZhenSheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++进阶哈希的应用相关的知识,希望对你有一定的参考价值。
目录
一:面试题:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】
一:面试题:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】
首先:40亿个整数要占用多少空间?
先来回顾一下:
1G = 1024MB
1024MB= 1024*1024 KB
1024*1024 KB = 1024*1024*1024 Byte = 2^30 Byte = 大约10亿 Byte
40亿个字节 = 4 G,所以4*4 = 16 G
以下两种方法内存消耗太大:
第一种方法:排序+二分查找
第二种方法:40亿个数放进一个set/unordered_set,查找 x 在不在,因为会有额外的附带消耗,left,right,parent,col.
===》节省内存的角度出发:使用2^32个比特位的位图进行映射,2^32 bit = 2^29 Byte
因为2^30 Byte = 10亿 Byte = 1G ,所以2^29 Byte = 512 MB
对于一个数x如何映射他的位置:
// 把x映射的比特位设置成1
void set(size_t x)
// 计算出他是第i个char对象中
size_t i = x / 8;
// 计算出他在这个char的第j个比特位上
size_t j = x % 8;
_bits[i] |= (1 << j);
// 把x映射的比特位设置成0
void reset(size_t x)
// 计算出他是第i个char对象中
size_t i = x / 8;
// 计算出他在这个char的第j个比特位上
size_t j = x % 8;
_bits[i] &= (~(1 << j));
如何判断一个数是否是1:
bool Test(size_t x)
//计算出他是第i个char对象中
size_t i = x / 8;
//计算出他在这个char的第j个比特位上
size_t j = x % 8;
return _bits[i] & (1 << j); //0就是假,非0就是真
二:给定100亿个整数,设计算法找到只出现一次的整数?
解决方法:用2个比特位标识一个值——消耗1G的内存
不在: 00
出现一次:01
出现多次:10
template<size_t N> class FindOnceValSet public: void set(size_t x) bool flag1 = _bs1.test(x); bool flag2 = _bs2.test(x); // 00 -> 01 if (flag1 == false && flag2 == false) _bs2.set(x); // 01 -> 10 else if (flag1 == false && flag2 == true) _bs1.set(x); _bs2.reset(x); // 10 -> 10 不处理,标识已经出现多次 void print_once_num() for (size_t i = 0; i < N; ++i) if (_bs1.test(i) == false && _bs2.test(i) == true) cout << i << endl;
三:哈希切割
给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?
以上是关于C++进阶哈希的应用的主要内容,如果未能解决你的问题,请参考以下文章
C++进阶第二十一篇——哈希(概念+哈希函数+哈希冲突+哈希表+哈希桶+代码实现)