哈希变形——位图

位图

位图简介

位图(bitmap),就是用位来存放某种状态,尤其适用于海量数据的处理。

我们可以算一算下面这个例子
unsigned int最大约为42亿9000万,每个占一位
存储所有的unsigned int只需要42亿9000万个位
42亿9000万个位 ≈ 5亿个字节
1byte = 8bit
1KB = 1024byte
1MB = 1024KB
1GB = 1024MB
10的9次字节约为1G,5亿个字节约为0.5G = 512mb

位图存储的要求是数据状态不是很多的情况,通常是用来判断某个数据存不存在的。
这个位一般是一位来存储一个数据,特殊情况下也可以是两位来存储,例如需要统计100亿个整型数中出现次数少于3的数,就需要两位来存储。
在STL中有一个bitset容器,其实就是位图。
位图

位图代码实现

下载:GitHub地址

#pragma once

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

typedef struct Bitmap
{
    size_t* _bit;
    size_t _range;
}Bitmap;

void BitmapInit(Bitmap* bm, size_t range);//初始化
void BitmapSet(Bitmap* bm, size_t num);//将某个数的位置置为1
void BitmapReset(Bitmap* bm, size_t num);//将某个数的位置置为0
bool BitmapTest(Bitmap* bm, size_t num);//判断某个数是否存在
void BitmapDestroy(Bitmap* bm);//销毁位图

void TestBitmap();//测试用例

void BitmapInit(Bitmap* bm, size_t range)
{
    assert(bm);
    bm->_range = range;
    bm->_bit = (size_t*)malloc(sizeof(size_t) * ((bm->_range >> 5) + 1));
    assert(bm->_bit);
    memset(bm->_bit, 0, sizeof(size_t) * ((bm->_range >> 5) + 1));
}

void BitmapSet(Bitmap* bm, size_t num)
{
    assert(bm);
    size_t index = num / 32;
    size_t position = num % 32;
    size_t set = 1;
    (*(bm->_bit + index)) |= (set << position);
}

void BitmapReset(Bitmap* bm, size_t num)
{
    assert(bm);
    size_t index = num / 32;
    size_t position = num % 32;
    size_t set = 1;
    (*(bm->_bit + index)) &= ~(set << position);
}

bool BitmapTest(Bitmap* bm, size_t num)
{
    assert(bm);
    size_t index = num / 32;
    size_t position = num % 32;
    size_t cmp = 1;
    return ((*(bm->_bit + index)) & (cmp << position)) ? true : false;
}

void BitmapDestroy(Bitmap* bm)
{
    assert(bm);
    free(bm->_bit);
    bm->_bit = NULL;
    bm->_range = 0;
}

void TestBitmap()
{
    Bitmap bm;
    BitmapInit(&bm, 100000);
    //插入
    BitmapSet(&bm, 444);
    BitmapSet(&bm, 555);
    BitmapSet(&bm, 789);
    BitmapSet(&bm, 3);
    BitmapSet(&bm, 4567);
    printf("掺入\n%d\n", BitmapTest(&bm, 444));
    printf("%d\n", BitmapTest(&bm, 443));
    printf("%d\n", BitmapTest(&bm, 555));
    printf("%d\n", BitmapTest(&bm, 789));
    printf("%d\n", BitmapTest(&bm, 3));
    printf("%d\n", BitmapTest(&bm, 4567));

    //删除
    BitmapReset(&bm, 555);
    BitmapReset(&bm, 555);
    BitmapReset(&bm, 444);
    BitmapReset(&bm, 444);
    BitmapReset(&bm, 789);
    BitmapReset(&bm, 5);
    printf("删除\n%d\n", BitmapTest(&bm, 444));
    printf("%d\n", BitmapTest(&bm, 555));
    printf("%d\n", BitmapTest(&bm, 789));
    printf("%d\n", BitmapTest(&bm, 5));

    BitmapDestroy(&bm);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值