bitmap 算法

今天看到了一个新的算法,折腾了一会儿,稍微明白了一点东西,留个笔记

-------------------------------------------------------------------------------------

     在普通的32位机器上,一个整形,在内存中占用了 32 bit 位的空间。我们可以利用这 32 bit 位分别代表 0-31 这些数字, bitmap 就是利用这种思想进行处理大量数据的排序和查找。

     优点:1.运算效率高,不许进行比较和移位;2.占用内存少,比如N=10000000;只需占用内存为N/8=1250000Byte=1.25M。 
      缺点:所有的数据不能重复。即不可对重复的数据进行排序和查找。

     比如:  2                           00000000000000000000000000000100

             再加一个4的时候变为    00000000000000000000000000010100

             再加一个1的时候变为    00000000000000000000000000010110

    这个算法的中心就是将数字映射到与之相对应的bit位上即可。

 

    假设需要排序或查找的数字最大数为 N = 1000000 (总数在N以内即可),则需要申请空间为 int a[1 + N/32] 即可。

    因此 bitmap 表为:

                a[0]--------->0-31 
             a[1]--------->32-63 
             a[2]--------->64-95 
             a[3]--------->96-127 
             ..........

 

     对于此算法中主要两个算法就是:

      1、获取数字 i 所在对应数组索引

      2、获取数字 i 所在bit数组的具体位置

 1     #include <stdio.h>  
 2       
 3     #define BITSPERWORD 32  
 4     #define SHIFT 5  
 5     #define MASK 0x1F  
 6     #define N 10000000  
 7       
 8     int a[1 + N/BITSPERWORD];//申请内存的大小  
 9       
10     //set 设置所在的bit位为1  
11     //clr 初始化所有的bit位为0  
12     //test 测试所在的bit为是否为1  
13       
14     void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }  
15     void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }  
16     int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }  
17       
18     int main()  
19     {   int i;  
20         for (i = 0; i < N; i++)  
21             clr(i);    
22         while (scanf("%d", &i) != EOF)  
23             set(i);  
24         for (i = 0; i < N; i++)  
25             if (test(i))  
26                 printf("%d\n", i);  
27       
28         return 0;  
29     }  

        如上代码所示:

           i >> SHIFT

        我们所用数字保存在32 bit位的内存中,因此 i >> SHIFT 就相当于 i / 2^5 即 i / 32 得到 i 所保存在的对应数组的索引。

          i & MASK

        MASK = 0x1F 就是31 换做二进制就是 11111 与 i 取 与运算 得到 i 二进制的后5位 也就是相当于 i 与 32 取余 即 i%32 。此时得到的就是 i 在相应的bit数组中所在的具体位置了。

          1 << (i & MASK)

         在 32 bit 中,将i所在bit位设为1。 得到 如: 0000000000000010000000000000000 的二进制数字

          a[i>>SHIFT] |= (1<<(i & MASK))

         将要改变数字 与 项对应的数字取或运算 即可将所需要添加的数字 添加到数组中去,完成一个添加过程。

 

 

参考链接:

http://blog.csdn.net/fanshadoop/article/details/7854672

http://www.cnblogs.com/huangxincheng/archive/2012/12/06/2804756.html

posted @ 2012-12-07 11:11  愤怒的豆沙包  阅读(291)  评论(0)    收藏  举报