所有比特的编号方法是,从低字节的低位比特位开始,第一个bit为0,最后一个bit为 n-1。

比如说,现在有个数组是这样子的,int a[4],那么
a[0]的比特位为0——31
a[1]的比特位为32——63
a[2]的比特位为64——95
a[3]的比特位为96——127

现在,我们根据下面这个程序来研究这个数组比特位的编号
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
 int a[4];
 for(int i=0;i<4;i++)
 {
  a[i]=1;
 }
 for(i=0;i<4;i++)
 {
  a[i]=a[i]<<4;
  cout<<a[i]<<endl;
 }

return 0;
}

结果是输出了4个16,也就是说,一开始的比特位是这样编排的00000000 00000000 00000000 00000001,在使用了位运算(向左移4位)之后成了这样00000000 00000000 00000000 00010000,很明显嘛,这比较符合我们的思维,但是这样子整个数组组织起来就相对比较麻烦咯,具体如下

0……………………0 0……………………0 0……………………0 0……………………0
a[0] 31~~0 a[1] 63~~32 a[2] 95~~64     a[3] 127~~96

//0……………………0 表示32位

利用位运算&实现取模运算%
位运算跟取模运算之间有着微妙的联系,确实很微妙,因为只有在某些特定的情况下才能使用位运算实现
先看个例子,100%32,100&31,经过计算,你会发现结果是一样的,那什么时候才会成立呢?这种计算对前一个数没有要求,不过对后一个的要求比较高,看一看32和31的二进制(统一用八位)表示,32=0010 0000,31=0001 1111,也就是说利用要利用这种算法,后一个数必须满足这样的条件,在取模运算中,该数的二进制表示只能有一位是1,也就是说,这个数必须是2的N次幂;在进行位运算的时候则取该数的前一个数的二进制表示来进行。

设置特定的位,清除特定的位
假如现在有个int类型的整数,i=0,将第5位置为1(写成二进制的时候,从右边数过来的第五位),假设本来都是零
i=i|(1<<5)

例子源码
#include <iostream>

using namespace std;

static int a=0;

void SetBit(int bit)
{
 a|=(1<<bit);
}

void ClearBit(int bit)
{
 a&=~(1<<bit);
}

int main(int argc, char* argv[])
{
 SetBit(5);
 cout<<a<<endl;
 ClearBit(5);
 cout<<a<<endl;
 return 0;
}

两个主要的运算:
字节位置=数据/32;(采用位运算即右移5位)

位位置=数据%32;(采用位运算即跟0X1F进行与操作)。

再来个例子,比如说现在我们有100这个数,于是,我们要将第100位置为1,也就是说,我们最少得有100位,100位等于12.5字节,因为一个int型是4个字节,所以我们必须定义一个这样的数组int[4],数组的位模型可以参考上面。现在,我们要对这个数组的100位进行置位操作嘛,那首先我得先知道100是在这个数组中的第几个元素嘛,所以,使用100/32,我现在要第100位,然后,每个数组元素是32位,进行运算之后,我就得到了我要置的位在那一个元素了,那确定了元素之后,我得知道,我要置位的是元素的哪一个位嘛,所以我就得知道求余的结果咯(纯粹数学知识的),所以就100%32咯,然后根据我上面的分析,模运算%与位运算&之间的一个微妙关系,那么我就可以采用这样的运算方式100&0x1F(0x1F是其实就是32),得到要置位的位置了。

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

因为unsigned int数据的最大范围在在40亿左右(需要40亿bit),40*10^8/1024*1024*8=476,因此只需申请512M的内存空间,每个bit位表示一个unsigned int。读入40亿个数,并设置相应的bit位为1.然后读取要查询的数,查看该bit是否为1,是1则存在,否则不存在。

现在我们把这道题目简化一下(40亿数据太大了。。。不想读文件,不想自己来产生这些数据。。)

///例子,包括算法实现(C语言实现,C++的话实在是太方便了,因为有bitset这个东西,所以C++的实现就没写下来)

假如有近100个不重复的正整数,范围在[1-100]之间,但是现在缺失了一些数,要确定缺失的数据。

因为是100个数,所以需要100位,100位=12.5字节,一个int类型是4字节,所以需要4个int类型,因此可以申请一个int数组,数组的大小为4,下面是程序源码。

#include <iostream>

using namespace std;

void SetBit(int bit)
{
 a|=(1<<bit);
}

void ClearBit(int bit)
{
 a&=~(1<<bit);
}
void SetBit(int n,int *bit)     //将逻辑位置为n的二进制位置为1
{
    bit[n>>5] |= (1<<((n&0x1F)-1));     //n>>SHIFT右移5位相当于除以32求算字节位置,n&0x1F相当于对32取余即求位位置。
}

void ClearBit(int n,int *bit)//将逻辑位置为n的二进制位置0
{
    bit[n>>5] &= ~(1<<((n&0x1F)-1));   //将逻辑位置为n的二进制位置0,原理同set操作
}

int TestBit(int n,int *bit)
{
    return bit[n>>5] & (1<<((n&0x1F)-1));        //测试逻辑位置为n的二进制位是否为1,如果为1,则返回非零值,注意,不是返回1,是返回非零值;如果为0,则返回0
}

int main(int argc, char* argv[])
{
 int a[100]={11,21,31,41,51,61,71,81,91,
    2,12,22,32,42,52,62,72,82,92,
    3,13,23,33,43,53,63,73,83,93,
    4,14,24,34,44,54,64,74,84,94,
    5,15,25,35,45,55,65,75,85,95,
    6,16,36,56,66,76,86,96,
    7,17,27,37,47,57,67,77,87,97,
    8,18,28,38,48,58,68,78,88,98,
    9,19,29,39,49,59,69,79,89,99,
    10,100};
 int bit[4];
 int i;
 for(i=0;i<4;i++)//将所以的比特位均置0
 {
  bit[i]=0;
 }
 for(i=0;i<100;i++)//根据数组里面的数据,将相应的比特位置为1
 {
  SetBit(a[i],bit);
 }
 for(i=1;i<=100;i++)
 {
  if(TestBit(i,bit)==0)
  {
   cout<<i<<" is not exist"<<endl;
  }
  else
  {
   cout<<i<<" is exist"<<endl;
  }
 }
 return 0;
}

对于SetBit和ClearBit两个函数,或许有人会有些疑问
主要是(n&0x1F)-1这个式子,估计有人会有些疑问,因为跟编程珠玑里面有些出入,因为1<<((n&0x1F)-1),很明显,如果没有进行移位的话,很显然,第一位已经是1了,举个例子,我们可以考虑下n为1的那种情况,很显然,这个时候没必要进行移位,直接bit[n>>5] |= 1就得到结果了,如果1<<(n&0x1F)的话,很显然,待会是将第二位置为1,所以这也就是(n&0x1F)-1)后面要减1的原因。

转载于:https://www.cnblogs.com/wsw-seu/p/8595740.html

位图bitmap应用相关推荐

  1. Redis 04_位图bitmap

    位图bitmap    [字节数组] 位图不是真正的数据类型,它是定义在字符串类型中 一个字符串类型的值最多能存储512M字节的内容 位上限:2^(9+10+10+3)=2^32b  --命令 设置某 ...

  2. 位图BITMAP结构

    数字媒体对于图像的处理肯定离不开对于位图的有关处理,首先要弄清楚位图的结构才能进行下面的工作.位图(Bitmap)图像又称点阵图或光栅图,它使用我们称为像素(象素,Pixel)的一格一格的小点来描述图 ...

  3. 算法与数据结构——位图BitMap

    一.介绍 1.1 什么是位图 在Java中有四种整数类型:byte.short.int.long. 1 byte(字节) = 8 bit(位) 1 int = 4 byte = 32 bit 所以我们 ...

  4. 位图Bitmap(基于Java实现)

    所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况.通常是用来判断某个数据存不存在的. 设计原则: 尽可能的最大化利用内存,极限挖掘.利用.发挥Java的性能. ...

  5. 十二、【数据结构】位图(bitmap)的详解与实现

    一.定义     --概念部分参考http://www.iteblog.com/archives/148 位图法就是bitmap的缩写.所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据, ...

  6. 数据结构--位图 BitMap

    文章目录 1. 位图 2. 位图代码 3. 布隆过滤器 Bloom Filter 4. 总结 1. 位图 我们有1千万个整数,整数的范围在1到1亿之间.如何快速查找某个整数是否在这1千万个整数中呢? ...

  7. 【ARM 嵌入式 C 入门及渐进 4-- Linux 位图 bitmap】

    文章目录 1.1 位图算法-bitmap 1.1.1 bitmap 使用场景示例 1.1.2 bitmap算法实现 1.1 位图算法-bitmap 位图算法,是指使用一个 bit 位来表示数据状态. ...

  8. oracle索引介绍之位图(bitmap)索引

    位图(BitMap)索引 前段时间听同事分享,偶尔讲起Oracle数据库的位图索引,顿时大感兴趣.说来惭愧,在这之前对位图索引一无所知,因此趁此机会写篇博文介绍下位图索引. 1. 案例 有张表名为ta ...

  9. 位图BitMap图像的读取与存储

    做图像处理时的源文件一般要用无损的图像文件格式,位图(BitMap)是windows系统下可存储无压缩图像的文件格式.要实现位图文件的读取和存储,首先要明白位图文件的的存储数据结构.位图文件由四部分依 ...

  10. 位图—BitMap和BitSet,布隆过滤器,Roaring Bitmap

    位图 简单来说就是为了压缩节省空间,才出现的. 举个例子: 你要是存储三个数字 2,5,10.这三个数字用java中的short类型来存储,也要6个Byte(short类型的内存空间是2Byte).一 ...

最新文章

  1. win7 能下node什么版本_Node.js 版本知多少?又该如何选择?
  2. 喜欢的Groove Coverage She
  3. HTML+CSS+JS实现 ❤️3D悬浮粒子翻转动效❤️
  4. buck电路 dac stm32_STM32定时器学习---基本定时器
  5. telnet后为啥打开的时防火墙_以前用散煤取暖时,农民很大方,换上天然气后就“蔫了”,为啥?...
  6. Oracle11g新特性:在线操作功能增强-表增加包含默认值的字段(转载)
  7. hibernate 乐观锁与悲观锁使用
  8. python手写一个迭代器_搞清楚 Python 的迭代器、可迭代对象、生成器
  9. arduino-esp32:LVGL中文字库(通用)
  10. 数学公式编辑器AxMath
  11. 实战PyQt5: 137-QChart图表之散点图
  12. python期货量化交易_基于vnpy搭建期货量化交易机器人(一)准备工作
  13. 在 dhcpd 中配置分配静态路由条目
  14. 增量式旋转编码器的使用,以arduino为例
  15. 协同过滤(collaborative filtering)
  16. VA虚拟应用匠心独妙,细节的精彩
  17. hex文件详解及常用合并方法介绍
  18. 卫星图在线浏览地址大全
  19. aizu/aoj-0118-Property Distribution
  20. python教程菜鸟教程学习路线

热门文章

  1. Google TakeOut图片下载器
  2. SQLite 3.31.0 发布,世界上使用量最大的数据库引擎
  3. SQL 使用总结四(关于索引)
  4. video 全屏显示
  5. android 仿美团悬浮,类似美团悬浮框的效果
  6. linux arm. 快速启动,教你如何快速启动Linux 系统
  7. 微信找不到nfc功能_手机的NFC如何使用?3分钟教会你!
  8. java mvc上传文件进度_java相关:springMVC+ajax实现文件上传且带进度条实例
  9. allergro音乐术语什么意思_这些关于刀具钢材的专业术语,你都知道是什么意思吗?...
  10. linux怎么编译sharedptr,如何使用智能指针(例如auto_ptr r shared_ptr)在Linux上使用C++生成链接列表数据结构?...