-
问题内容:大数据量的相同记录次数统计
- 原讨论链接:http://community.csdn.net/expert/topicview1.asp?id=5092570
- 所属论坛:数据结构与算法
审核组:其他
- 提问者:ruilyn
解决者:spirit_sheng
- 感谢:spirit_sheng
- 关键字:函数 个数 专题开发/技术/项目 数据结构与算法 二进制 字节 int 算法 整数 index unsigned 批批
- 答案:
一个2G的二进制文件里面都是ip地址,需要统计一下一共有多少个ip地址,请问该用什么算法效率高点?
文件大概是这样的
3D 33 81 3D 3D 95 21 2E...
(61.51.129.61 61.149.33.46...)
---------------------------------------------------------------
每个IP由4字节组成, 2G的二进制文件包括 512M 个IP记录
每个IP由4字节组成, 将这四字节组成可以看成一个整数, 你的问题就变换成:
512M个整数中, 去除重复后有多少个整数
对于一般的应用来说, 一般IP记录的重复度都比较大, 512M个记录, 非重复的IP个数一般为1000万个以下(1000万约等于10M), 对此, 楼主可以估计一下具体个数
则可以分配一个 16M (1600万个) 整数数组(16M = 2^24
#define N 0x01000000
unsigned int ip[N];
#define Mask 0x00FFFFFF
1. 初始化整个数组, 将各元素都设置为0, 因为不存在0.0.0.0 的IP, 所以, 元素为0表示没有IP与之对应
2. 读入文件中的数据, 并对每个数据unsigned int x进行如下处理(注: 不要一个一个读, 要成批批的读, 否则速度会很慢: 如(可以一次读入64K字节内容, 即16K个整数, 然后对这16K个整数进行处理):
unsigned int index = x & Mask;
unsigned int y = ip[index];
while ((y) && (y != x))
{
index = (index + 11) & Mask;
y = ip[index];
}
ip[index] = x;
对于所有数据, 完成以上过程后, 进入下一步
3. 扫描计数
int count = 0;
for (int i=0; i<N; i++)
if (ip[i]) count++;
此即为哈希做法,
其:
1. unsigned int ip[N]; 即为哈希表
2. unsigned int index = x & Mask; 即为哈希函数
3. index = (index + 11) & Mask; 即为二次哈希函数
条件 ((y) && (y != x)) 表示目前定位的索引有内容, 且内容与x不相同
所以, while 退出时, 表示此索引位置没有数据, 或数据为x
此算法空间消耗64M, 时间复杂度接近O(n)
- 评价:
给朵鲜花(0)
扔个鸡蛋(0)