C++进阶哈希的应用

Posted Huang_ZhenSheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++进阶哈希的应用相关的知识,希望对你有一定的参考价值。

目录

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

二:给定100亿个整数,设计算法找到只出现一次的整数?

三:哈希切割


一:面试题:给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++进阶哈希的应用

C++进阶第二十一篇——哈希(概念+哈希函数+哈希冲突+哈希表+哈希桶+代码实现)

C++进阶哈希表

C++进阶哈希表

C++进阶第二十二篇——unordered_map和unordered_set(容器接口介绍和使用+底层代码实现)

C++进阶---Map和Set使用及模拟实现