一、bitmap算法思想

32位机器上,一个整形,比如int a; 在内存中占32bit位,可以用对应的32bit位对应十进制的0-31个数,bitmap算法利用这种思想处理大量数据的排序与查询. 

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

比如: 
          第一个4就是 
          00000000000000000000000000010000 
          而输入2的时候 
          00000000000000000000000000010100 
          输入3时候 
          00000000000000000000000000011100 
          输入1的时候 
          00000000000000000000000000011110

思想比较简单,关键是十进制和二进制bit位需要一个map图,把十进制的数映射到bit位。下面详细说明这个map映射表。

假设需要排序或者查找的总数N=10000000,那么我们需要申请内存空间的大小为int a[1 + N/32],其中:a[0]在内存中占32为可以对应十进制数0-31,依次类推: 
bitmap表为:

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

步骤:

1.  求十进制0-N对应在数组a中的下标: 
     十进制0-31,对应在a[0]中,先由十进制数n转换为与32的可转化为对应在数组a中的下标。比如n=24,那么 n/32=0,则24对应在数组a中的下标为0。又比如n=60,那么           n/32=1,则60对应在数组a中的下标为1,同理可以计算0-N在数组a中的下标。

2.  求0-N对应0-31中的对应位: 
    十进制0-31就对应0-31,而32-63则对应也是0-31,即给定一个数n可以通过模32求得对应0-31中的数。

3.  利用移位0-31使得对应32bit位为1.

#include <stdio.h>  

#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000 int a[1 + N/BITSPERWORD];//申请内存的大小 //set 设置所在的bit位为1
//clr 初始化所有的bit位为0
//test 测试所在的bit为是否为1 void set(int i) { a[i>>SHIFT] |= (1<<(i & MASK)); }
void clr(int i) { a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int test(int i){ return a[i>>SHIFT] & (1<<(i & MASK)); } int main()
{ int i;
for (i = 0; i < N; i++)
clr(i);
while (scanf("%d", &i) != EOF)
set(i);
for (i = 0; i < N; i++)
if (test(i))
printf("%d\n", i); return 0;
}

  解析本例:

1.i>>SHIFT: 
其中SHIFT=5,即i右移5为,2^5=32,相当于i/32,即求出十进制i对应在数组a中的下标。比如i=20,通过i>>SHIFT=20>>5=0 可求得i=20的下标为0;

2.i & MASK: 
其中MASK=0X1F,十六进制转化为十进制为31,二进制为0001 1111,i&(0001 1111)相当于保留i的后5位。

比如i=23,二进制为:0001 0111,那么 
                         0001 0111 
                   &    0001 1111 = 0001 0111 十进制为:23 
比如i=83,二进制为:0000 0000 0101 0011,那么 
                          0000 0000 0101 0011 
                     &   0000 0000 0001 0000 = 0000 0000 0001 0011 十进制为:19

i & MASK相当于i%32。

3.1<<(i & MASK) 
相当于把1左移 (i & MASK)位。 
比如(i & MASK)=20,那么i<<20就相当于: 
         0000 0000 0000 0000 0000 0000 0000 0001 >>20 
      =0000 0000 0000 1000 0000 0000 0000 0000

同理:

void set(int i)
{
a[i>>SHIFT] |= (1<<(i & MASK));
} 等价于: void set(int i)
{
a[i/32] |= (1<<(i%32));
}

  

浅谈bitmap算法的更多相关文章

  1. 浅谈分词算法(5)基于字的分词方法(bi-LSTM)

    目录 前言 目录 循环神经网络 基于LSTM的分词 Embedding 数据预处理 模型 如何添加用户词典 前言 很早便规划的浅谈分词算法,总共分为了五个部分,想聊聊自己在各种场景中使用到的分词方法做 ...

  2. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  3. 浅谈分词算法(3)基于字的分词方法(HMM)

    目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...

  4. 浅谈分词算法基于字的分词方法(HMM)

    前言 在浅谈分词算法(1)分词中的基本问题我们讨论过基于词典的分词和基于字的分词两大类,在浅谈分词算法(2)基于词典的分词方法文中我们利用n-gram实现了基于词典的分词方法.在(1)中,我们也讨论了 ...

  5. 浅谈Manacher算法与扩展KMP之间的联系

    首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解.网上解法颇多.时间复杂度也不尽同样,这里列述几种常见的解法. 解法一   ...

  6. 浅谈Tarjan算法

    从这里开始 预备知识 两个数组 Tarjan 算法的应用 求割点和割边 求点-双连通分量 求边-双连通分量 求强连通分量 预备知识 设无向图$G_{0} = (V_{0}, E_{0})$,其中$V_ ...

  7. 浅谈KMP算法及其next[]数组

    KMP算法是众多优秀的模式串匹配算法中较早诞生的一个,也是相对最为人所知的一个. 算法实现简单,运行效率高,时间复杂度为O(n+m)(n和m分别为目标串和模式串的长度) 当字符串长度和字符集大小的比值 ...

  8. 浅谈时间复杂度- 算法衡量标准Big O

    写在前面: 今天有一场考试,考到了Big-O的知识点,考到了一道原题,原题的答案我记住了,但实际题目有一些改动导致答案有所改动,为此作者决定重新整理一下复杂度相关知识点 Efficiency and ...

  9. 浅谈聚类算法(K-means)

    聚类算法(K-means)目的是将n个对象根据它们各自属性分成k个不同的簇,使得簇内各个对象的相似度尽可能高,而各簇之间的相似度尽量小. 而如何评测相似度呢,采用的准则函数是误差平方和(因此也叫K-均 ...

随机推荐

  1. (转)Unity3D研究院之将场景导出XML或JSON或二进制并且解析还原场景

    自:http://www.xuanyusong.com/archives/1919 导出Unity场景的所有游戏对象信息,一种是XML一种是JSON.本篇文章我们把游戏场景中游戏对象的.旋转.缩放.平 ...

  2. HttpWebRequest: Remote server returns error 503 Server Unavailable

      I have a client server application written in C# .Net 2.0. I have had the client/server response/r ...

  3. 编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息

    随着高速(20M)宽带.HTPC.大容量硬盘(3T)的普及,下载高清片并利用大屏幕观看也成为普通的事情. 随着下载影片的增多,管理就有了问题,有时在茫茫文件夹下找寻一个影片也是一件费时费力的事. 于是 ...

  4. 安装ecshop2.7时候的错误处理 php版本不兼容引起

    装ECShop2.7.3出现了一堆问题,主要是因为PHP版本过高引起的,不愿意降低版本,则只能一个个解决啦!这些问题包括:preg_replace.cls_image::gd_version.end( ...

  5. android中使用WebView请求本地网页

    使用WebView的方式请参考我的上一篇文章:android中使用WebView请求网页 这里说一下请求本地网页的方法: 本地网页应该把网页保存在src/main/assets目录下: webView ...

  6. Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解

    Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解 一.Jquery遍历筛选数组 1.jquery grep()筛选遍历数组 $().ready( function(){ v ...

  7. Go语言使用Beego的ORM插入Mysql后,时区不一致的解决方案

    一.解决方案: 方案一: orm.Debug = false orm.DefaultTimeLoc = time.UTC orm.RegisterDriver("mysql", o ...

  8. Java 判断Windows下某个进程是否运行

    public static void main(String[] args) { String keyWord = "chrome.exe"; Runtime runtime = ...

  9. 关于LINUX在中断(硬软)中不能睡眠的真正原因

    摘自http://bbs.chinaunix.net/thread-2115820-1-1.html 4楼的回答 先把中断处理流程给出来 1.进入中断处理程序--->2.保存关键上下文----& ...

  10. tornado url配置

    Note tornado是支持虚拟主机的,在同一端口上根据域名区分app http://www.tornadoweb.org/en/stable/web.html#application-config ...