转:Bit-Map思想与2-BitMap思想

1. Bit-map思想

给你一堆西安市的电话号码列表,数量大概在千万级,要求从中找出所有重复的电话号码,需要时间复杂度尽可能小。

目前西安市的电话号码大概都以8开头,为8位,也就是类似于82678578这样子

二重暴力搜索时间复杂度太高,这里我们不予考虑。

容易想到的办法就是建立一个标志数组,int boolean都行,用相应的位置值来代替这个号码是否出现,

根据数组的可直接存取特性,来提高效率。但是你是否想过或测试过

int[] a = new int[100000000];

boolean[] a = new boolean[100000000]; //需要大概100M*4的内存,如果

这样类似的语句是否可以通过编译并且执行。

再仔细思考下,就会发现,int型的字段太过于占空间,我们只需要知道这个号码存在与否,

所以最简单的0和1就够用了,能表示0和1的最小存储单位是什么呢?

是内存中的一位。//int 为4 byte  ,那么1个int 可以存放32位;

申请一个int一维数组,那么可以当作为列为32位的二维数组,

|                            32位                                      |

int a[0] |0000000000000000000000000000000000000|

int a[1] |0000000000000000000000000000000000000|

………………

int a[N] |0000000000000000000000000000000000000|

每一个电话号码,用上面的一位表示,如电话80000000可以用a[0]的第一位表示,有则是表示为1,无则是0

OK,这就是bitmap的思想。

将西安市的电话号码去掉开头的8,就可以将其映射到一个1到10000000的数组中。

8bit是1byte,1024byte是1kb,1024kb是1mb

所以10000000个bit占用的空间为10000000/8/1024/1024mb大概为1mb多些,

这对于现在大家动不动几G的内存来说,完全是小菜一碟。

2. 2-Bitmap实现

在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数。*/

每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义
    #include<stdio.h>  
    #include<memory.h>  
    //用char数组存储2-Bitmap,不用考虑大小端内存的问题  
    unsigned char flags[1000]; //数组大小自定义   
    unsigned get_val(int idx)  
    {

|    8 bit     |

|00 00 00 00|  //映射3 2 1 0

|00 00 00 00| //表示7 6 5 4

……

|00000000|

int i = idx/4;  //一个char 表示4个数,
        int j = idx%4;  
        unsigned ret = (flags[i]&(0x3<<(2*j)))>>(2*j);  //0x3是0011 j的范围为0-3,因此0x3<<(2*j)范围为00000011到11000000

如7 i= ,j=3 那么flags[1]&11000000, 得到的是|00 00 00 00| //表示7 6 5 4
        return ret;  
    }  
      
    unsigned set_val(int idx, unsigned int val)  
    {  
        int i = idx/4;  
        int j = idx%4;  
        unsigned tmp = (flags[i]&~((0x3<<(2*j))&0xff)) | (((val%4)<<(2*j))&0xff);  
        flags[i] = tmp;  
        return 0;  
    }  
    unsigned add_one(int idx)  
    {  
        if (get_val(idx)>=2) {  //这一位置上已经出现过了??
            return 1;  
        }  
        else  {  
            set_val(idx, get_val(idx)+1);  
            return 0;  
        }  
    }  
      
    //只测试非负数的情况;  
    //假如考虑负数的话,需增加一个2-Bitmap数组.  
    int a[]={1, 3, 5, 7, 9, 1, 3, 5, 7, 1, 3, 5,1, 3, 1,10,2,4,6,8,0};  
      
    int main()  
    {  
        int i;  
        memset(flags, 0, sizeof(flags));  
          
        printf("原数组为:");  
        for(i=0;i < sizeof(a)/sizeof(int); ++i)  {  
            printf("%d  ", a[i]);  
            add_one(a[i]);  
        }  
        printf("\r\n");  
      
        printf("只出现过一次的数:");  
        for(i=0;i < 100; ++i)  {  
            if(get_val(i) == 1)  
                printf("%d  ", i);  
        }  
        printf("\r\n");  
      
        return 0;  
    }

除了用2-Bitmap来计数标记以外,也可以用两个1-Bitmap来实现(如果考虑正负数的情况,就四个1-Bitmap)

转:Bit-Map思想与2-BitMap思想相关推荐

  1. 高效大数据开发之 bitmap 思想的应用

    作者:xmxiong,PCG 运营开发工程师 数据仓库的数据统计,可以归纳为三类:增量类.累计类.留存类.而累计类又分为历史至今的累计与最近一段时间内的累计(比如滚动月活跃天,滚动周活跃天,最近 N ...

  2. java 算法思想,Java/12_算法思想.md at master · Jn6/Java · GitHub

    常见的算法思想 一.排序思想 1.前K个高频元素(347) 问题描述:给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = ...

  3. Spring的AOP思想和实现AOP思想的框架AspectJ

    章节目标:详细解释什么是Spring AOP思想和对于该思想实现的AspectJ框架的实现用法. 一.AOP面向切面编程 1.AOP概述 AOP(Aspect Orient Programming)面 ...

  4. 如何建立编程思想和提高编程思想

    一.首先,什么是编程思想? 编程思想是一种指导思想,这个指导思想,将会诱发你如何写代码的行为. 如果理解这话的意思呢?打个比方,中华文明千百年在民众心中形成了一个"统一天下"的思想 ...

  5. 2023年春国家开放大学思想道德与法治/思想道德修养与法律基础大作业答案

    一.材料分析题(本题共1小题,每小题 80分,共80分.) 李桓英,世界著名麻风病防治专家,首都医科大学附属北京友谊医院医生.北京热带医学研究所研究员.上世纪五十年代初,她曾在世界卫生组织工作 7年, ...

  6. java编程思想 入门_java编程思想学习(基础)

    第一章 java介绍 1.编程的本质: 机器空间:解空间 问题空间:实际需要解决的业务问题,将该问题抽象化,在解空间中对问题建模. 编程就是建立问题空间和机器空间中的关联 面向对象编程思想: 1.万物 ...

  7. java面向对象编程思想_Java面向对象编程思想

    面向对象三个特征:封装.继承.多态 封装: 语法:属性私有化(private).提供相对应的get/set 的方法进行访问(public). 在set/get的方法中对属性的数据 做相对应的业务逻辑的 ...

  8. java面向对象编程的思想_java面向对象编程思想

    Java与面向对象 一.类与对象 (1)对象是Java程序的核心,对象可以看成是静态属性(成员变量)和动态属性(方法)的封装体 (2)类是用来创建同一类型的对象的"模板",在一个类 ...

  9. css布局的基本思想,流行的CSS思想之——浅析OOCSS

    流行的CSS思想之--浅析OOCSS 更新时间:2015年12月29日14时02分 来源:传智播客前端与移动开发学科 浏览次数: --前言 随着Web技术的发展,每一个网站都离不开CSS(层叠样式表) ...

最新文章

  1. 基于Faster RCNN的医学图像检测(肺结节检测)
  2. 【opencv】9.批量命名图片文件std::sprintf
  3. 惊人体积,无码改造,黑月V1.7.4增强版[20110810]
  4. C++中volatile关键字
  5. 正则表达式的基本语法[转]
  6. DEVC++编译奇怪报错问题解决
  7. javaScript 对象访问属性的另一种方式
  8. 力扣-1877 数组中最大数对和的最小值
  9. 物流管理系统c语言程序设计,C语言程序设计物流管理系统.doc
  10. 做出产品不难,做好产品必须高手
  11. 没火多久就停业,故宫火锅店咋了?
  12. 请问做亚马逊,注册P卡是用个人名义还是公司名义?
  13. 我是如何做到使得开源系统拥有安全的防护框架的呢?
  14. 普里姆(Prim)算法 Java实现(最小生成树)
  15. 3D数学基础——欧拉角与万向节死锁
  16. matlab fread 详细讲解
  17. 【Basic Algebra】群论学习整理
  18. C语言位运算农夫过河,位运算常见操作和农夫过河问题(C++实现)
  19. 【C/C++服务器开发】文件,文件描述符,I/O多路复用,select / poll / epoll 详解
  20. 睡眠研究可以帮助创建更好的AI模型吗?

热门文章

  1. openEuler系统配置yum镜像源
  2. 服务器的文件共享,服务器文件共享设置
  3. java 视频 缩略图_Java截取视频文件缩略图
  4. mega_[MEGA DEAL]完整的Android开发人员课程–构建14个应用程序(91%折扣)
  5. 皮一皮:中国好男友!!!
  6. 皮一皮:直男这下懂了吧...
  7. ES 在数据量很大的情况下(数十亿级别)如何提高查询效率?
  8. 每日一皮:我当程序员的时候也是...
  9. 漫漫优化路,总会错几步!记一次接口优化!
  10. 面试:说说Java中的 volatile 关键词?