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

    我在前面的随笔里已经写过关于处理海量数据的哈希表和Trie的方法了,本文提到的是常用方法之一:Bitmap,测试数据是100万条随机数。

    Bitmap是用于处理有限位数的整数,理论上,对于1GB的内存,处理的整数范围大约在0-8,000,000,000内,即一般处理10亿以内,同时也是10位数以内的数据,可实现的操作有存储,排序,查找,删除,查重

    而朴素的方法处理10亿的整数需要40GB以上的内存空间,所以,在int用32位表示的机器上,理论内存空间使用比例为1:32,我在下面的代码里用到的测试数据是100万条1亿以内的随机数,完成增删查排序功能。

    欢迎有共同学习兴趣的同学加好友探讨学习哦~~^_^

    代码:

      1 #include <stdlib.h>
      2 #include <string.h>
      3 #include <time.h>
      4 #include <fstream>
      5 #include <sys/timeb.h>
      6 #include <basetsd.h>
      7 /**
      8 * @author:zanzan101
      9 */
     10 using namespace std;
     11 
     12 unsigned int* build_bitmap(const unsigned int m)
     13 {
     14     // 建立一个空bitmap
     15     // 我这里是用1位表示一条记录,没有查重的功能,如果用2位表示,或者使用双bitmap,则可以实现查重
     16     unsigned int* p = new unsigned int[1 + m/(8*sizeof(unsigned int))];
     17     memset(p, 0, m/8 + sizeof(unsigned int));
     18     return p;
     19 }
     20 
     21 void set_bit(unsigned int* arr, unsigned int n)
     22 {
     23     // 常数时间插入任何一个数
     24     unsigned int pos = n/(8*sizeof(unsigned int));
     25     unsigned int tmp = n%(8*sizeof(unsigned int));
     26     unsigned int msk = (unsigned int)1 << tmp;
     27     arr[pos] |= msk;
     28 }
     29 unsigned int get_bit(unsigned int* arr, unsigned int n)
     30 {
     31     // 常数时间查找任何一个数
     32     unsigned int pos = n/(8*sizeof(unsigned int));
     33     unsigned int tmp = n%(8*sizeof(unsigned int));
     34     unsigned int msk = (unsigned int)1 << tmp;
     35     tmp = arr[pos];
     36     tmp &= msk;
     37     return tmp>0?1:0;
     38 }
     39 void delete_bit(unsigned int* arr, unsigned int n)
     40 {
     41     // 常数时间删除任何一个数
     42     unsigned int pos = n/(8*sizeof(unsigned int));
     43     unsigned int tmp = n%(8*sizeof(unsigned int));
     44     unsigned int msk = (unsigned int)1 << tmp;
     45     msk = ~msk;
     46     arr[pos] &= msk;
     47 }
     48 
     49 
     50 void save_bitmap(unsigned int* arr, unsigned int m)
     51 {
     52     ofstream output_file;
     53     output_file.open("D:\test_bitmap___.txt");
     54     if(!output_file.is_open())
     55         return;
     56 
     57     // bitmap 本身就是有序的,只需从前往后依次遍历访问即可有序输出
     58     for(unsigned int i = 0; i < m; i++)
     59         if(get_bit(arr, i))
     60             output_file << i << endl;
     61 }
     62 
     63 void print_bitmap(unsigned int* arr, unsigned int m)
     64 {
     65     if(m > 100)
     66     {
     67         printf("数据量过大,不便于在屏幕上显示,已存入文件:D:\test_bitmap___.txt
    ");
     68         save_bitmap(arr, m);
     69         return;                //数据量过大时,还是保存到文件里比较好~~~
     70     }
     71 
     72     // bitmap 本身就是有序的,只需从前往后依次遍历访问即可有序输出
     73     for(int i = 0; i < m; i++)
     74         if(get_bit(arr, i))
     75             printf("%8d ", i);
     76     printf("
    ");
     77 }
     78 
     79 unsigned int big_rand(const unsigned int max)
     80 {
     81     unsigned int sum = 0;
     82     int tmp = max/RAND_MAX;
     83     if(!tmp)
     84         return rand()%max;
     85 
     86     int round = rand()%tmp;
     87     sum += RAND_MAX*round;
     88     sum += rand();
     89     return sum;
     90 }
     91 
     92 int main()
     93 {
     94     timeb time_begin;
     95     timeb time_end;
     96     unsigned int seconds;
     97     unsigned int miseconds;
     98 
     99     const unsigned int MAX = 100000000;
    100     unsigned int* bitmap = build_bitmap(MAX);
    101     srand(time(0));
    102     // 测试插入功能
    103     // 插入100万条随机数
    104     printf(">> 插入:100万条%u以内的随机数
    ", MAX);
    105     for(int i = 0; i < 1000000; i++)
    106         set_bit(bitmap, big_rand(MAX));
    107 
    108     // 测试排序功能
    109     // bitmap本身就是有序的
    110     printf(">> 排序:
    ");
    111     print_bitmap(bitmap, MAX);
    112 
    113     // 测试查找功能
    114     printf(">> 查找:100个%u以内的随机数
    由于是随机数,其实找到每个数的概率是0.01,下面只显示找到的情况
    ", MAX);
    115     ftime(&time_begin);    
    116     int ran;
    117     for(int i = 0; i < 100; i++)
    118     {
    119         ran = big_rand(MAX);
    120         if(get_bit(bitmap, ran))
    121             printf("	%d存在!
    ", ran);
    122 //        由于找到的概率比较小,下面就不显示没有找到的情况了
    123 //        else                                
    124 //            printf("	%d不存在!
    ", ran);
    125     }
    126     ftime(&time_end);
    127     seconds = time_end.time - time_begin.time;
    128     miseconds = time_end.millitm - time_begin.millitm;
    129     miseconds = seconds * 1000 + miseconds;
    130     printf(">> 100次查找总共耗时:%u毫秒
    ", miseconds);
    131 
    132     // 现插入现找
    133     ran = big_rand(MAX);
    134     set_bit(bitmap, ran);
    135     printf(">> 查找:现插入随机数%d,再查找它
    ", ran);
    136 
    137     if(get_bit(bitmap, ran))
    138         printf("	%d存在!
    ", ran);
    139     else
    140         printf("	%d不存在!
    ", ran);
    141 
    142     // 测试删除功能
    143     // 删除刚才插入的那个随机数
    144 
    145     printf(">> 删除:刚才插入的那个随机数%d删掉,之后再查找它
    ", ran);
    146     delete_bit(bitmap, ran);
    147     if(get_bit(bitmap, ran))
    148         printf("	%d存在!
    ", ran);
    149     else
    150         printf("	%d不存在!
    ", ran);
    151     delete[] bitmap;
    152     system("pause");
    153     return 0;
    154 }

    输出结果:

    >> 插入:100万条100000000以内的随机数
    >> 排序:
    数据量过大,不便于在屏幕上显示,已存入文件:D:	est_bitmap___.txt
    >> 查找:100个100000000以内的随机数
    由于是随机数,其实找到每个数的概率是0.01,下面只显示找到的情况
            92857475存在!
            19411480存在!
            58457743存在!
            37785850存在!
            26831485存在!
    >> 100次查找总共耗时:0毫秒
    >> 查找:现插入随机数82440561,再查找它
            82440561存在!
    >> 删除:刚才插入的那个随机数82440561删掉,之后再查找它
            82440561不存在!
    请按任意键继续. . .
  • 相关阅读:
    maven导入项目时出现“Cannot read lifecycle mapping metadata …… invalid END header (bad central directory offset)pom”错误的解决方法
    Eclipse下使用Git
    Sprint Boot入门(1):创建第一个Spring Boot应用
    Gradle入门(6):创建Web应用项目
    Gradle入门(5):创建二进制发布版本
    maven在windows10系统下安装配置和打包war
    Windows10系统下安装配置Tomcat 9.0.1
    面试题1
    Json序列化帮助类
    NPOI帮助类
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3348649.html
Copyright © 2011-2022 走看看