数据结构--位图

先了解一下位运算的基础知识:

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

比如,给出一个数组:int[] array = new int[4]。那么:

a[0] -- a[4] 的比特位分别为:0--31,32--63,64--95,96--127

下面我们依据一个程序探究数组比特位的编号:

复制代码
public class BitNumber {
    public static void main(String[] args) {
        int[] array = new int[4];
        for (int i = 0; i < array.length; i++) {
            array[i] = 16;
        }
        for (int i = 0; i < array.length; i++) {
            array[i] = array[i] >> 4;
            System.out.println(array[i]);
        }
    }
}
复制代码
结果是输出了4个1,也就是说刚开始比特位编排为:0000 0000 0001 0000,使用位运算,使其右移了4位,变为:0000 0000 0000 0001.

 

利用位运算& 进行取模

位运算跟取模运算之间联系微妙,具体可从下面的例子中看出来:

100%32;100&31

上述公式的结果是一样的,让我们探究一下他们的原理:

100%32 的取余运算,将取到一百减去3个32之后的余数为4。 100&31是进行按位与运算,31=0001 1111;100=0110 0100,当他们进行按位与时,大于等于32的那部分将给消去,留下的便是余数。

当然上述运算成立的条件便是 32对应位置的数必须是2的N次幂。

 

特定位的设置与清除

假如现在 int a = 0; 现在a的编码全部为0,现在要将其从右往左第5个位置设置为1,然后再清除上述操作

复制代码
static int a = 0;
    public static void main(String[] args) {
        a |= (1<<5);     // | 按位或操作 ,双目运算符 a = a|(1<<5);
        System.out.println(a);
        a &= ~(1<<5);    // & 按位与操作,双目运算符, ~ 按位非操作,单目运算符
        System.out.println(a);
    }
复制代码
上述运算的结果分别为32 0.

 

字节位置与位位置

 一个int是4个字节,每个字节有32bit,我们可以将数据存储在这些位内。比如我们要存储100这个数,我们只需在位置100存储一个1。将第100位置为1,也就是说最少需要有100个位置,每个位置1bit,100个位置需要12.5字节,因为一个int型是4字节,所以我们需要定义一个数组 int[4]。

现在我们要对这个数组的100位进行操作,首先要知道100在这个数组中的第几个元素,每个数组元素都是32位,那么100所在的位置就是100/32,也就是 100>>5。然后在元素中的位置也就是:100%32,也就是100&31,也就是100&0x1F。

给一个例子:

给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则存在,否则不存在。

您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站大部分内容收集于互联网,如果有侵权内容、不妥之处,请联系删除。敬请谅解!

  Previous post Going Home
Next post   从一个 PHP 工程师的角度来看 Go

添加新评论

  关于博主【WANG-FEiHU】

Duplicate
-----------Complicate
--------------------------Appreciate
-----------------------------------------Fate

闻先后,术专攻
三人有师
习得文武艺,货与帝王家
人性不曾变,资本永无眠

-----------花有重开日,人无再少年-----------

  分类目录

  monitor(TD)

往前一步是黄昏,退后一步是人生

渡口边最后一面洒下了句点,与你若只如初见 何须感伤离别

生活远没有咖啡那么苦涩,关键是喝它的人怎么品味!每个人都喜欢和向往随心所欲的生活,殊不知随心所欲根本不是生活。

如果错过了太阳时你流泪了,那么你也要错过群星了。

不如意的时候不要尽往悲伤里钻,想想有笑声的日子吧。

我不明白为什么要那么在意别人的看法,评头论足只是无聊人的消遣,何必看得如临大敌。如果你不吃别人家的饭,就别太把别人的话放在心上。