bitmap运用实例

来源:互联网 发布:古埃及文明造假知乎 编辑:程序博客网 时间:2024/06/14 16:42

问题实例】

1)已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数。

8位最多99 999 999,大概需要99m个bit,大概10几m字节的内存即可。 (可以理解为从0-99 999 999的数字,每个数字对应一个Bit位,所以只需要99M个Bit==1.2MBytes,这样,就用了小小的1.2M左右的内存表示了所有的8位数的电话)


2)  2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。 
将bit-map扩展一下,用2bit表示一个数即可,0表示未出现,1表示出现一次,2表示出现2次及以上,在遍历这些数的时候,如果对应位置的值是0,则将其置为1;如果是1,将其置为2;如果是2,则保持不变。或者我们不用2bit来进行表示,我们用两个bit-map即可模拟实现这个2bit-map,都是一样的道理。

实现:

  1. // TestWin32.cpp : Defines the entry point for the console application.  
  2. #include "stdafx.h"  
  3.   
  4. #include<memory.h>    
  5.   
  6. //用char数组存储2-Bitmap,不用考虑大小端内存的问题    
  7. unsigned char flags[1000]; //数组大小自定义     
  8. unsigned get_val(int idx)  {   
  9. //  |    8 bit  |  
  10. //  |00 00 00 00|  //映射3 2 1 0  
  11. //  |00 00 00 00|  //表示7 6 5 4  
  12. //  ……  
  13. //  |00 00 00 00|  
  14.   
  15.     int i = idx/4;  //一个char 表示4个数,  
  16.     int j = idx%4;    
  17.     unsigned ret = (flags[i]&(0x3<<(2*j)))>>(2*j);    
  18.     //0x3是0011 j的范围为0-3,因此0x3<<(2*j)范围为00000011到11000000 如idx=7 i=1 ,j=3 那么flags[1]&11000000, 得到的是|00 00 00 00|  
  19.     //表示7 6 5 4  
  20.    return ret;    
  21. }    
  22.         
  23. unsigned set_val(int idx, unsigned int val)  {    
  24.     int i = idx/4;    
  25.     int j = idx%4;    
  26.     unsigned tmp = (flags[i]&~((0x3<<(2*j))&0xff)) | (((val%4)<<(2*j))&0xff);    
  27.     flags[i] = tmp;    
  28.     return 0;    
  29. }    
  30. unsigned add_one(int idx)    
  31. {    
  32.     if (get_val(idx)>=2) {  //这一位置上已经出现过了??  
  33.         return 1;    
  34.     }  else  {    
  35.         set_val(idx, get_val(idx)+1);    
  36.         return 0;    
  37.     }    
  38. }    
  39.         
  40. //只测试非负数的情况;    
  41. //假如考虑负数的话,需增加一个2-Bitmap数组.    
  42. int a[]={1, 3, 5, 7, 9, 1, 3, 5, 7, 1, 3, 5,1, 3, 1,10,2,4,6,8,0};    
  43.         
  44. int main()   {    
  45.     int i;    
  46.     memset(flags, 0, sizeof(flags));    
  47.             
  48.     printf("原数组为:");    
  49.     for(i=0;i < sizeof(a)/sizeof(int); ++i)  {    
  50.         printf("%d  ", a[i]);    
  51.         add_one(a[i]);    
  52.     }    
  53.     printf("\r\n");    
  54.         
  55.     printf("只出现过一次的数:");    
  56.     for(i=0;i < 100; ++i)  {    
  57.         if(get_val(i) == 1)    
  58.             printf("%d  ", i);    
  59.         }    
  60.     printf("\r\n");    
  61.       
  62.     return 0;    
  63. }  
原创粉丝点击