1. 给定一个大小超过100G的文件,其中存在IP地址,找到其中出现次数最多的IP地址。(哈希划分)
要查找IP地址,首先要将100G文件加载到内存以哈希表的形式将其储存起来。其中哈希表中的数组元素一个键值对构成。各IP地址(4字节)作为Key值,IP地址出现的次数作为Value值。在对哈希表进行遍历查找出现次数最多的IP地址。
但是一般的内存不可能有100G,无法将文件中的所有IP地址都保存起来,所以上述的方法不可行。因此采取哈希文件划分的方法来进行处理。
假设现在有1G的内存,将这1G内存构造出一个哈希表,哈希表中的数组元素为一键值对Key-Value,其中Key用于存储IP地址,占4个字节,Value表示某一IP地址出现的次数,也用4字节来存放。因此1G的数组中最多有2^27(1GB = 2^30B,2^30B/8B = 2^27)个数组元素:
(1)对100G文件进行第一次遍历读取IP地址。读取一个IP地址,根据某种哈希函数计算得到一个哈希数hash,此时的哈希函数可以使hash在1G数组的下标所能表示的范围内。使hash对100求模,将求模后的结果与0进行比较。
1)读取第一个IP地址ip1,并计算hash1。如果hash1 % 100 == 0,则将该ip1存放在哈希表中,下标由hash1表示(此处Key为ip1,Value为1)。如果求模运算不为0,则跳过ip1,读取第二个IP地址。
2)读取第二个IP地址ip2,并计算hash2。
如果hash2 % 100 == 0;则将ip2存放在哈希表中,如果ip2等于ip1,则将ip1对应的Value值加1。否则,将ip2存放在下标为hash2表示的数组元素内,并填写相应的Key和Value。
如果求模运算不为0,则跳过ip2,读取下一个IP地址。
3)读取第三个IP地址。与2)进行类似的操作。
..........
当读取完文件的最后一个IP地址,并对其作出相应处理之后。对这1G内存的哈希表的插入操作就结束了。此时哈希表中存放的都是满足:hash % 100 == 0的IP地址。然后对该哈希表进行查找,找到出现次数最多的IP地址(如IP0),将其IP地址和出现的次数保存起来。然后将哈希表清空。
(2)对100G文件中进行第二次遍历读取IP地址。读取一个IP地址,根据上述哈希函数计算得到一个哈希数hash,此时的哈希函数可以使hash在1G数组的下标所能表示的范围内。使hash对100求模,将求模后的结果与1进行比较。
1)读取第一个IP地址ip1,并计算hash1。如果hash1 % 100 == 1,则将该ip1存放在哈希表中,下标由hash1表示(此处Key为ip1,Value为1)。如果求模运算不为1,则跳过ip1,读取第二个IP地址。
2)读取第二个IP地址ip2,并计算hash2。
如果hash2 % 100 == 1;则将ip2存放在哈希表中,如果ip2等于ip1,则将ip1对应的Value值加1。否则,将ip2存放在下标为hash2表示的数组元素内,并填写相应的Key和Value。
如果求模运算不为1,则跳过ip2,读取下一个IP地址。