bitmap位图法

位图法定义

位图法就是bitmap的缩写,所谓bitmap,是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。

例如,要判断一千万个人的状态,每个人只有两种状态:男人,女人,可以用0,1表示。那么就可以开一个int数组,一个int有32个位,就可以表示32个人。操作的时候可以使用位操作。

本文地址:http://www.cnblogs.com/archimedes/p/bitmap.html,转载请注明源地址。

数据结构

unsigned int bit[N];

在这个数组里面,可以存储 N * sizeof(int) * 8个数据,但是最大的数只能是N * sizeof(int)  * 8 - 1。假如,我们要存储的数据范围为0-15,则我们只需要使得N=1,这样就可以把数据存进去。如下图:

数据为【5,1,7,15,0,4,6,10】,则存入这个结构中的情况为

位图法应用

一、给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中

申请512M的内存

一个bit位代表一个unsigned int值

读入40亿个数,设置相应的bit位

读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在

二、使用位图法判断整形数组是否存在重复

判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。位图法比较适合于这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到 5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>

bool hasDuplicatedItem(int *a, int len)
{
    int length, max, i;
    length = len;
    max = a[0];
    for(i = 1; i < length; i++){
        if(a[i] > max)
            max = a[i];
    }
    int *arr;
    arr = (int*)malloc(sizeof(int) * (max + 1));
    for(i = 0; i < length; i++){
        if(arr[a[i]])
            return true;
        else
            arr[a[i]] = 1;
    }
    return false;
}

int main()
{
    int length;
    int test[] = {0,1,2,3,45,12,13};
    length = (sizeof(test) / sizeof(test[0]));
    if(hasDuplicatedItem(test, length))
        printf("hasDuplicatedItem!\n");
    else
        printf("hasNoDuplicatedItem!\n");
    return 0;
}

三、使用位图法进行整形数组排序

首先遍历数组,得到数组的最大最小值,然后根据这个最大最小值来缩小bitmap的范围。这里需要注意对于int的负数,都要转化为unsigned int来处理,而且取位的时候,数字要减去最小值。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>

void bitmapSort(int *a, int len)
{
    int length, max, min, i, index;
    length = len;
    min = max = a[0];
    //找出数组最大值
    for(i = 1; i < length; i++){
        if(a[i] > max){
            max = a[i];
        }
        if(min > a[i]) {
            min = a[i];
        }
    }
    //得到位图数组
    int *arr;
    arr = (int*)malloc(sizeof(int) * (max - min + 1));
    for(i = 0; i < length; i++){
        index = a[i] - min;
        arr[index]++;
    }
    //重整a中的元素
    int arr_length;
    arr_length = max - min + 1;
    index = 0;
    for(i = 0; i < arr_length; i++){
        while(arr[i] > 0){
            a[index] = i + min;
            index++;
            arr[i]--;
        }
    }
}

void print(int *a, int n)
{
    int i;
    for(i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
}

int main()
{
    int length;
    int test[] = {50,1,26,3,45,12,13};
    length = sizeof(test) / sizeof(test[0]);
    print(test, length);
    bitmapSort(test, length);
    print(test, length);
    return 0;
}

四、位图法存数据

输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10,000,000 输入文件中没有重复的整数,没有其他数据与该整数相关联。

输出: 按升序排列这些数。

约束:有 1MB多(不超过2MB) 的内存空间可用,有充足的硬盘空间。

#include<stdio.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

/* a[i>>SHIFT]是第i位应该在第几个int上 */
/* (1<<(i & MASK))是第i位在该int上的第几个bit */

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;
}
时间: 2024-10-06 09:49:05

bitmap位图法的相关文章

BitMap位图与海量数据的理解

1. Bit Map算法简介 来自于<编程珠玑>.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. 2. Bit Map的基本思想 我们先来看一个具体的例子,假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复).那么我们就可以采用Bit-map的方法来达到排序的目的.要表示8个数,我们就只需要8个Bit(1Bytes),首先我们开辟1Byte的空间,将

位图法统计活跃用户

Setbit 的实际应用 场景: 1亿个用户, 每个用户 登陆/做任意操作 ,记为 今天活跃,否则记为不活跃 每周评出: 有奖活跃用户: 连续7天活动每月评,等等... 思路: Userid dt active1 2013-07-27 11 2013-0726 1 如果是放在表中, 1:表急剧增大,2:要用group ,sum运算,计算较慢 用: 位图法 bit-mapLog0721: '011001...............0' ......log0726 : '011001.......

BitMap位图

BitMap位图算法https://blog.csdn.net/varyall/article/details/79662029 常见面试题 题1:在2.5亿个整数找出不重复的整数,内存不足以容纳着2.5亿个整数. 方案1:使用2-Bitmap 每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义.然后遍历修改Bitmap中的对应位,如果是00则变01,01则变10,10则保持不变.遍历修改完后,最后遍历输出对应位是01的整数. 方案2:分治法 先将2.5亿个数划分成

【Bitmap Index】B-Tree索引与Bitmap位图索引的锁代价比较研究

通过以下实验,来验证Bitmap位图索引较之普通的B-Tree索引锁的“高昂代价”.位图索引会带来“位图段级锁”,实际使用过程一定要充分了解不同索引带来的锁代价情况. 1.为比较区别,创建两种索引类型的测试表1)在表t_bitmap上创建位图索引[email protected]> create table t_bitmap (id number(10), name varchar2(10),sex varchar2(1)); Table created. [email protected]>

集合的检索:位图法

位图法 位图法是一种逻辑上很巧妙的描述集合的方法. 如集合S={2,4,1,5,12},它用位图描述就是 0110 1100 0000 1000,两个字节即可描述S,左边是低阶位.用bitset<16>存储的话就是{[15].[14]....[1].[0]}={0001000000110110}. 用位图对集合进行描述后,就很方便进行集合的运算,如交.并和差. 下面来演示具体操作 集合S={1,2,4,5},集合T={2,5,8,10} 集合S的位图是 0110110000000000 集合T

ios 基本图形的绘制 基于bitmap 位图

内容包括 图片水印,图片裁剪,屏幕截图,背景平铺 1.图片水印功能 #import "UIImage+MJ.h" @implementation UIImage (MJ) + (instancetype)waterImageWithBg:(NSString *)bg logo:(NSString *)logo { UIImage *bgImage = [UIImage imageNamed:bg]; // 1.创建一个基于位图的上下文(开启一个基于位图的上下文) UIGraphicsB

重温delphi之:如何将Bitmap位图与base64字符串相互转换

先引用delphi自带的单元 uses EncdDecd; 然后就可以使用下面二个函数了: by 菩提树下的杨过 http://yjmyzz.cnblogs.com/ ///将Bitmap位图转化为base64字符串function BitmapToString(img:TBitmap):string ;var  ms:TMemoryStream;  ss:TStringStream;  s:string;begin    ms := TMemoryStream.Create;    img.S

Bitmap 位图

1.  概述 位图(bitmap)是一种非常常用的结构,在索引,数据压缩等方面有广泛应用.本文介绍了位图的实现方法及其应用场景. 2. 位图实现 (1)自己实现 在位图中,每个元素为"0"或"1",表示其对应的元素不存在或者存在. #define INT_BITS sizeof(int) #define SHIFT 5 // 2^5=32 #define MASK 0x1f // 2^5=32 #define MAX 1024*1024*1024 //max num

Bitmap 位图 Java实现

一.结构思想 以 bit 作为存储单位进行布尔值存取的数据结构. 表现为:给定第i位,该bit为1则表示true,为0则表示false. 二.使用场景及优点 适用于对布尔或0.1值进行(大量)存取的场景. 如:记录一个用户365天的签到记录,签了为true,没签为false.若是以普通key/value数据结构,每个用户都需要记录365条,当用户量很大时会造成巨大的空间开销. 因此运用位图的话,每天签到记录只占1个位(bit),一共就365位,则只需48个字节就能容纳. 优点: 能够进行低空间消