首页 > 技术文章 > 如何统计不同电话号码的个数

hardy-wang 2020-06-12 15:14 原文

题目描述:

已知某个文件内包含一些电话号码,每个号码为 8 位数字,统计不同号码的个数。

分析与解答:

这个题目本质上也是求解数据重复的问题,对于这类问题,首先会考虑位图法。对本题而言,8 位电话号码可以表示的范围为 00000000~99999999。如果用 1bit 表示一个号码,那么总共需要 1 亿个 bit,总共需要大约 100MB 的内存。
通过上面的分析可知,这道题的主要思路:申请一个位图并初始化为 0,然后遍历所有电话号码,把遍历到的电话号码对应的位图中的 bit 设置为 1。当遍历完成后,如果 bit 值为 1,则表示这个电话号码在文件中存在,否则这个 bit 对应的电话号码在文件中不存在。所以 bit 值为 1 的数量就是不同电话号码的个数。
求解这道题时,最核心的算法是如何确定电话号码对应的是位图中的哪一位。下面重点介绍这个转化的方法,这里使用下面的对应方法。
00000000 对应位图最后一位:0×0000…000001。
00000001 对应位图倒数第二位:0×0000…0000010(1 向左移 1 位)。
00000002 对应位图倒数第三位:0×0000…0000100(1 向左移 2 位)。
……
00000012 对应位图的倒数第十三位:0×0000…0001 0000 0000 0000。
通常而言,位图都是通过一个整数数组来实现的(这里假设一个整数占用 4B)。由此可以得出,通过电话号码获取位图中对应位置的方法为(假设电话号码为 P):
1)通过 P/32 就可以计算出该电话号码在 bitmap 数组中的下标(因为每个整数占用 32bit,通过这个公式就可以确定这个电话号码需要移动多少个 32 位,也就是可以确定它对应的 bit 在数组中的位置)。
2)通过 P%32 就可以计算出这个电话号码在这个整型数字中具体的 bit 的位置,也就是 1 这个数字对应的左移次数。因此,只要把 1 向左移 P%32 位,然后把得到的值与这个数组中的值做或运算,就可以把这个电话号码在位图中对应的位设置为 1。
这个转换的操作可以通过一个非常简单的函数来实现:

推荐阅读