0x00 基礎算法和經常使用技巧

0x01位運算

與、或、異或

運算符 解釋 例子
& 對應位上兩個數都爲\(1\)結果爲\(1​\),反之爲\(0​\) 101 & 001 = 001
| 對應位上兩個數有一個爲\(1\)結果爲\(1\),反之爲\(0\) 101 | 010 = 111
異或^ 對應位上兩個數不一樣爲\(1\),反之爲\(0\) 101 ^ 100 = 001

特別的異或的逆運算仍是異或,( a ^ b ) ^ b = a優化

取反

~一個數的每一位取反,~ 1001 = 0110spa

注意這裏的~是按位取反,!是邏輯取反code

左移、右移

左移(>>)把二進制的每一位向左移動,多餘的捨棄,右側補0注意可能會移到符號位上,致使變成負數get

右移(<<)把二進制的每一位向右移動,多餘的捨棄,左側補0table

注意左移右移的運算優先級低於加減,因此a << 1 + 1 = a << ( 1 + 1 )class

位運算的應用

代替乘除

a << i等價於\(a \times 2^i\)二進制

a >> i等價於\(a\div 2^i\)im

a * 10 = ( a << 3) + ( a << 1 )tab

集合運算

若是用二進制數來表示集合,還有一些集合運算集合

操做 集合表示 位運算操做
交集 $a \cap b $ a & b
並集 \(a \cup b\) a | b
補集 \(\overline a\) ~ a

枚舉子集

for( register int i = x ; i ; i = ( i - 1 ) & x );

優化常數

下面的寫法,在必定程度上能夠優化常數

判斷奇偶

if( x & 1 ) = if( x % 2 )

交換兩個數

inline void swap( int & x , int & y ) { x ^ y ^ x ^ y;}

判斷兩個數符號是否相同

inline bool isSameSign(int x, int y) {  // 有 0 的狀況例外
  return (x ^ y) >= 0;
  // true 表示 x 和 y 有相同的符號,false 表示 x,y 有相反的符號。
}

求平均值

inline int getAverage( int x , int y ) { return (x + y) >> 1; }
相關文章
相關標籤/搜索