zoukankan      html  css  js  c++  java
  • 学习Bloom Filter,处理“海量”数据

    今天晚上做了一个在线测评,其中涉及到了一个海量数据处理的问题,下面是这个问题定义及我的解法,其中用到了Bloom Filter,这个东西乍一听让人摸不着头脑,仔细看看,感觉就是Hash+Bitmap的合体,综合了Hash散列定位和Bitmap用位存储的特点。

    问题:

     已存在20亿个URL,每个URL平均长度为64字节,在2G内存的环境中,设计一个较快的算法去判断一个新的URL是否在那20亿URL中,可以出现一定几率的误判。

    思路:

    使用Bloom Filter的方法,将这20亿个URL映射到内存中,该内存空间初始化为0,每个URL映射到一个bit位,遍历已有的20亿个URL,并将对应的bit位置为1,检查新的URL所对应的bit位,该位为0则表示新URL不在集合中,该位为1则表示新URL在集合中,映射方法采用哈希算法,理论上2G内存可以处理160亿位,而我使用了40亿位,约占用500M内存空间。

    代码:

     1 #include <string.h>
     2 #include <fstream>
     3 #include <iostream>
     4 
     5 using namespace  std;
     6 
     7 unsigned int* build_memory_of_bloomfilter(const unsigned int m)
     8 {
     9     // 建立一个空bitmap
    10     // 我这里是用1位表示一条记录,没有查重的功能,如果用2位表示,或者使用双bitmap,则可以实现查重
    11     unsigned int* p = new unsigned int[1 + m/(8*sizeof(unsigned int))];
    12     memset(p, 0, m/8 + sizeof(unsigned int));
    13     return p;
    14 }
    15 
    16 void set_bit(unsigned int* arr, unsigned int n)
    17 {
    18     unsigned int pos = n/(8*sizeof(unsigned int));
    19     unsigned int tmp = n%(8*sizeof(unsigned int));
    20     unsigned int msk = (unsigned int)1 << tmp;
    21     arr[pos] |= msk;
    22 }
    23 unsigned int get_bit(unsigned int* arr, unsigned int n)
    24 {
    25     unsigned int pos = n/(8*sizeof(unsigned int));
    26     unsigned int tmp = n%(8*sizeof(unsigned int));
    27     unsigned int msk = (unsigned int)1 << tmp;
    28     tmp = arr[pos];
    29     tmp &= msk;
    30     return tmp>0?1:0;
    31 }
    32 
    33 static const int hashtable_length    = 4000000000;
    34 unsigned int hash_function(const char* str)
    35 {
    36     const char* end_of_str = str+strlen(str);
    37     unsigned int sum = 0;
    38     while (end_of_str - str > 3)
    39     {
    40         sum ^= *((unsigned int*)str);
    41         str += 4;
    42     }
    43     char tmp[4] = {0};
    44     strcpy(tmp, str);
    45     sum ^= (unsigned int)*((unsigned int*)tmp);
    46     sum %= hashtable_length;
    47     memset(tmp, 0, 4);
    48 
    49     return sum;
    50 }
    51 int main()
    52 {
    53 
    54     const unsigned int MAX = 4000000000;                        // 设置总位数为40亿,目标是处理20亿URL
    55     unsigned int* memory_of_bloomfilter = build_memory_of_bloomfilter(MAX);
    56 
    57 
    58     ifstream input_file;
    59     input_file.open("D:/URL.txt");
    60     if(!input_file)
    61         return -1;
    62 
    63     char buff[256];
    64 
    65     // 设置20亿个URL的位
    66     while(input_file.getline(buff, 255))
    67         set_bit(memory_of_bloomfilter, hash_function(buff));
    68 
    69     cin>> buff;    // 输入新的URL
    70     if(get_bit(memory_of_bloomfilter, hash_function(buff)))
    71         cout<< "集合中已经存在!" <<endl;
    72     else
    73         cout<< "集合中不存在!" <<endl;
    74 
    75     input_file.close();
    76     delete[] buff;
    77     delete[] memory_of_bloomfilter;
    78     return 0;
    79 }

    输出结果:

    http://s1.hao123img.com/res/images/search_logo/web_png8.png
    集合中已经存在!
  • 相关阅读:
    WPF中StringToImage和BoolToImage简单用法
    linux定时执行任务
    进程管理
    防火墙和网络安全
    ICMP
    茶叶知识
    插花、花艺、种植
    AD域中添加了一个策略导致的问题
    写一个工具,将批量的“规章制度”文件上传到广西门户网站对应的文档库中
    SharePoint Online 创建门户网站系列之定制栏目
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3358180.html
Copyright © 2011-2022 走看看