CSDN=>FAQ=>FAQ 展示
  • 问题内容:大数据量的相同记录次数统计
  • 原讨论链接: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)
相关FAQ
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo