位向量的理解

🌷一、位向量

☘️1.问题

我们先看一个问题,如果我们有一千万个不重复的数,现在要对这一千万个数进行排序。

🥇解决办法

每一个数都用int来表示,然后把一千万数都读到内存中,然后进行排序。

🥈消耗内存

首先一个int类型是四个字节,那么一千万个数就是:10000000 * 4B = 39062.5KB = 38M

🌱2.位向量

位向量简单解释就是由二进制0和1组成的向量

那么如何用位向量来表示数呢?

假设现在有一个向量[0, 1, 0, 1, 0] ,从右往左看第1、3 都是1,那么这个位向量就表示:1、3两个数,并且是有序的,从右到左依次递增。

🥇解决办法

同样还是上面那个问题,还是一千万个数,将这一千万个数用位向量表示,这样就会自动进行排序,除此之外还可以节省内存。

🥈消耗内存

一个int是4字节也就是32位,能表示32个数,一千万个数就是:1000 0000 / 32 = 312500 * 4B = 1220KB = 1.2M

🌸二、位向量操作

假设现在有60个数,要用位向量来表示,那么60个数,一个int能表示32个数,所以需要长度为(60 / 32) + 1 的int数组来表示。如下图,将60个数放到下面长度为2的int数组中int[] a = new int[2]

在这里插入图片描述

🥝1.定位元素位置

🍑1.1 理论过程

无论是往位向量中放元素,还是从位向量中删除元素或者判断位向量中是否有某个元素,都需要定位到这个元素在位向量中的位置。

这个位置指两个位置:第一个是在数组索引的位置;第二个是在这个索引处intbit位。当然这里也不只是int类型,也可以是long类型,如果是long类型那么每一个数组元素就可以表示64个元素。后续的位向量都用int类型来示例。

首先是确定放在数组的哪一个位置,首先一个int是32位,那么数组的每一个元素能表示的数据范围如下

a[1] = [0, 31]
a[2] = [32, 63]
a[3] = [64, 95]

那么可以推断出,判断一个元素放在数组的那个位置,就是用这个元素除以数组数据类型的长度的到的商就是这个元素在数组中的位置,这里int的长度是32,那么就用这个元素来除以32就可以定位到这个元素在数组的索引位置。

那么具体在哪个bit位,由于每个元素都不一样,那么在一个int长度内的元素的余也就不一样,如果余数一样,那么商肯定不一样。所以定位bit最简单的就余数是多少,那么该元素的bit位置就是多少。

🍓1.2 计算过程

假设我们要操作的元素是m,那么首先来计算它除以32的商和余。

在这里插入图片描述

根据上面这个公式计算,商是p余数是s。所以元素m在数组的索引是p,在bit的位置是s

这里还有个问题就是p可以用a[p]就能表示。

那么s怎么表示,最简单的做法就是移位操作,让1来进行左移s位就能把元素在bit位上表示出来。这里还有个问题就是如果是1左移s位,是不是就是多了一位,其实这里之所以左移s而不是s-1是因为刚好整除的情况,如果元素m刚好能整除32,那么余就是0,1 << 0刚好是在第一位。

所以,元素在位向量中的定位:

🥇数组索引位置可以用a[p]来表示

🥈**bit位可以用1 << s来表示**

🍑 1.3实际操作

假设m就是37,首先计算它的商和余,来确定位置

  • 计算商

由上面的推导公式可知,计算商就是将37进行右移动5位

37的二进制

在这里插入图片描述

右移动5位之后结果为1,也就是商为1

在这里插入图片描述

  • 计算余数

也就是计算37 & (2^5 - 1)

37的二进制

在这里插入图片描述

2^5 - 1 的二进制

在这里插入图片描述

37 & (2^5 - 1)

在这里插入图片描述

通过上面的计算得到余数是5,该元素在bit位上的表示为 1<< 5

1 << 5

在这里插入图片描述

所以37在位向量中的位置:索引位置位a[1];bit位置位 1<<5。

🌲1.放数据

🎃1.1 理论过程

定位到数据的位置之后,怎么将数据放到位向量中,首先数组索引位置a[p]是确定的,bit的位置是1<<s

假设除了该bit位,其它的bit位也有数据,放数据的原则就是将本bit位设置为1,其它位置保持不变。

那么就用1 << sbit位其它的位置做一个或运算,其它位置如果是1,那么进行或运算也不会改变,而且1 << s进行或运算无论这个位置以前是什么,和1 << s进行或运算后都会变成1的。

🏔️1.2 实际操作

a[1] 的32个bit位原来可能有值,所以要进行或运算将新的37放进去,这里是第一次放元素,所以a[1]是0,然后进行或运算,然后将值赋值给a[1],这样就完成了整个操作

a[1] = a[1] | (1 << 5)

在这里插入图片描述

🌳2.删除数据

🎋2.1 理论过程

删除元素的过程也很简单,就是将对应的bit位置为0,首先该元素的bit位置是1<<s,那么删除元素,就是将该位置的1变为0,其它位置保持不变。

首先将1<<s取反,也就是~运算,这样1 << s位置就变成0了,其它位置就变成1了,然后再和索引处的值进行与运算,其它位置的值和1进行与运算都不会改变成,而1 << s变成0,做与运算无论这个位置以前是什么值,和0做与运算之后都会变成0

🍅2.2 实际操作

首先取反

~(1 << 5)

在这里插入图片描述

然后进行与运算

a[1] = a[1] & ~(1 << 5)

在这里插入图片描述

🌴3.判断数据

🍇3.1 理论过程

如果某一个数据在位向量中的bit位是1那么表示该位向量中有该元素,如果是0表示该位向量中没有该元素。

判断1<<s是否有元素,就将其它位置的元素全部变成0,该位置保持不动。那么要将其它位置变成0,就和0进行与运算。

🍈3.2 实际操作

1 << 5做与运算,将其它位置值置为0

a[1] & (1 << 5)

在这里插入图片描述

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值