位运算
WHY?
因为在计算机的运算过程:
二进制数无法进行直接运算,先把二进制数转化为十进制数进行运算,将所得到的十进制数再转化为二进制数。
即:二进制数→十进制数→运算→十进制数→二进制数;
这样无疑会大大降低计算机的运算速度。
有什么方法可以直接将二进数进行运算呢?
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
WHAT?
二进制的运算符
位与 &
举例:
10110
&
00101
————
00100(两个都为1,结果为1,其他所有情况为0)
位或 |
举例:
10110
|
00101
————
10111(其中之一为1则为1,两个0为0)
左移 <<
10110
<<
1
————
101100(数字向左移一位 相当于 * 2 )
右移 >>
10110
>
1
————
1011(数字向右移一位 相当于 / 2)
取反 ~
~10110
————
01001(把所有的二进制位取反 把1→0,0→1)
异或 ^
10110
^
00101
————
10011(如果2个1或2个0,结果为0,其他所有情况为1,即 只要两个数不同,则为1)
(也可以简单的理解为如果单个二进制位^0则结果不变,^1则取反 )
HOW?
二进制的算法虽然快,但我们很难想到我们会求到什么数,
比如:10|11 = 1010|1011 = 1011 = 13;
那么二进制的运算可以做什么呢?
求奇偶性
在十进制数中,奇数的个位数为1、3、5、7、9,偶数的个位数都为0、2、4、8;
在二进制中则为:奇数的个位数为1,偶数的个位数为0(二进制数满二进一)
例:10→1010 最后一位是0
11→1011 最后一位是1
∴
奇数 & 1 == 1;
偶数 & 1 == 0;
1可以写成0000001;
∴若二进制数为奇数,&1结果为1;若为偶数,&1结果则为0;一个二进制数&1就相当于除了个位以外全部为0.
例:1011
&
0001
——————
0001 == 1
……………………
1010
&
0001
———————
0000 == 0
乘除运算
若乘以或除以2的指数(如:2、4、8、16、32……)
可以用“<<”(即* 乘以)或“>>”(即/ 除以)
例:1<<1 == 1 * 2 == 2;
1<<2 == 1 * 2 * 2 == 4;
4>>1 == 4 / 2 == 2;
4>>2 == 4 / 2 / 2 == 1;
在DP中为了节省内存使用滚动数组(这个在DP中详细介绍)
滚动数组:dp[2][N](因为上下来回滚动,所以只用到了0 1 ,所以为2)
注意:
还要考虑优先级的问题:
二进制运算的优先级是所有运算中最低的。
所以如果使用二进制运算要加“()”。