今天面试中遇到一个查找问题,典型的属于哈希查找算法可以解决,我居然懵逼了很尴尬 ̄□ ̄||,之前在数据结构中学过Hash表,后来有没有复习,现在在这里再总结归纳一下吧。
没有复习之前提到Hash我一直以为是IPFS里面的Hash校验算法,算是理解比较片面吧。
使用哈希表快速查找字符串
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希表hashtable(key,value) 的做法其实很简单,就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。
而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位
看了之后明明是之前考研学过的东西,要被自己气死了。。。
从两个文件(各含50亿个url)中找出共同的url、不同的url
问题:
给定a、b两个文件,各存放50亿个url,每个url各占用64字节,内存限制是4G,如何找出a、b文件共同的url?
解法一:
可以估计每个文件的大小为5G*64=300G (50亿是5000000000,即5G),远大于4G。
所以不可能将其完全加载到内存中处理,考虑采取分而治之的方法。
遍历文件a,对每个url求取hash(url)%1000,然后根据所得值将url分别存储到1000个小文件(设为a0,a1,…a999)当中。这样每个小文件的大小约为300M。
遍历文件b,采取和a相同的方法将url分别存储到1000个小文件(b0,b1….b999)中。
这样处理后,所有可能相同的url都在对应的小文件(a0 vs b0, a1 vs b1….a999 vs b999)当中,不对应的小文件(比如a0 vs b99)不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。
比如对于a0 vs b0,我们可以遍历a0,将其中的url存储到hash_map当中。然后遍历b0,如果url在hash_map中,则说明此url在a和b中同时存在,保存到文件中即可。
如果分成的小文件不均匀,导致有些小文件太大(比如大于2G),可以考虑将这些太大的小文件再按类似的方法分成小小文件即可。