位屏蔽(Bitmasking)中屏蔽字赋值语句 mask | (1 << j) 的解释
位屏蔽(Bitmasking)中屏蔽位赋值语句 mask | (1 << j) 的解释
什么是位屏蔽
位屏蔽是一种以较小代价标识大量数据的方法,比如一个有N个元素的集合,我们可以用一个N位(bit)的值来表示这个集合的子集合。这个值通常被称为mask(屏蔽字)。
例如 10000101 表示集合[1,2,3 … 8]的子集合1,3,8 。屏蔽字在保存的时候实际上是一个二进制形式的Integer。
mask | (1 << j)
在算法中,构造子集合时会用到set(i, mask)方法,这个方法内的主要语句是 mask | (1 << i) 。 如果初次见到这个代码,可能会一头雾水,或者误认为这是一个判断条件,实际上这是一句赋值代码。这里有两个运算符需要解释。
- “|” 或运算符。这个运算符是在二进制计算中的“或”。
例: 10001001 | 00000110 = 10001111 相信如何运算一目了然。 - “<<” 左移运算符。将二进制数的各位全部左移若干位,右边空出的位用0填补,高位溢出部分舍弃。
例:1 << 1 = 10 10000001 << 3 = 00001000
通过上面两个运算符的解释,现在这个赋值语句就容易理解了。首先,(1 << i) 表示将二进制数1左移i位,得到新的二进制数 100…0 (i个0),然后将这个二进制数与mask进行一个或运算。注意这个二进制数除了高位i位,其他都是0,这样进行或运算,实际上是将mask的i位置1。
平时在coding的过程中,我们常接触的是整型数字,突然使用二进制数的值和运算符可能会混淆,难以理解。因此,熟悉二进制数、二进制运算符号也是必要的。
在了解这些基本知识的基础上,接下来的推送我会用位屏蔽结合DP解决一些经典的算法问题。