關於位操作的幾個小智力題
看!大灰機!Σ( ° △ °|||)︴
wow~ (′⊙o⊙)? 看!小灰象!!!
是的,昨天,在平和友好的氣氛中,矮矮胖胖憨態可掬的小飛象同學向我陸陸續續地描述了一個問題。
今天早上我終於想明白了問題應該是什麼樣的。
假設 ,其中 表示 和 的二進位表示的逐位與。
給定正整數 求使得 的最小正整數 。
例如 , , , , , , , ,此時。
分析 和 的二進位表示就發現差別從 的二進位表示的最右一個「 」開始,將「 」變為「 」。
於是 和 的逐位與的實際效果就是「將 的二進位表示的最右一個「1」變為「0」!
所以 就等於 的二進位表示中的「1」的個數。
於是這個方法可以用來判斷「正整數 是否是 2 的冪?」,只要判斷 是否為0即可。
於是就聯想起來看到過的一些和「位」有關的小題目:
? 在一個0-1串 中(圖中假設 是1個位元組,8個比特),希望知道右數第 個比特是1還是0(從右往左數時從0開始計數)(圖中假設 )。
解答:
AND(n,1<<i)n
說明:
?在一個0-1串 中,希望將右數第 個比特設置為1。
解答:
OR(n,1<<i)n
說明:
? 在一個0-1串 中,希望將右數第 個比特設置為0。
解答:
AND(n,NOT(1<<i))n
說明:
? 給出兩個0-1串 和 ,以及兩個二進位位的位置 和 。寫一個方法來將 中的第 到 位替換為 (假設 的長度恰好可以填入,結果是 是 中從第 位開始到第 位的子串)。
解答:先把 中相應位置都設置為「0」,然後對 做向左移位,然後逐位或。
? 數組中,只有一個數出現一次,剩下都出現兩次,找出這個出現一次的數。
解答:將所有數都做逐位異或。
說明: 表示異或運算(即模2加法), , , , 。異或運算滿足交換律、結合律,且具有一個重要性質 。
此外,還有一些規律如 , , , ,等等。
事實上,考慮元素數最少的有限域 ,就會發現 ,也即「與」是其中的乘法,「異或」是其中的加法。
所以交換律、結合律、分配律都是自然的。
? 數組中,只有兩個數出現一次,剩下都出現兩次,找出出現一次的數。
解答: 將所有數都做逐位異或。得到結果是這兩個數的異或結果,其中必定有某一位是1。對於原來的數組,根據這個位置是1還是0進行分類。於是這兩個數一定不在同一類,而且每一類都是「只有一個數出現一次,剩下都出現兩次」。
? 給定兩個0-1串 和 ,計算需要改變 的多少位才能得到 。
解答:數一數 中「1」的個數。
? 假設 和 都是正整數,證明: 。
解答:注意到 ,而後 。
說明:類似地,可以證明 。
( )
? 將 , 兩個數的值進行交換,並且不使用任何的中間變數。
解答: , , 。
其中 表示異或運算(即模2加法), , , , 。
註:主要利用了 。
? 最後一個問題:假設 ,給定正整數 求使得 是2的冪的最小正整數 。
(解答留給讀者吧)
最後,還是補充幾句吧,網上還有一些據說是筆試題/面試題——例如下面幾個,然而我並不喜歡,就列著玩兒玩兒不分析了。
- 數組中,只有一個數出現一次,剩下都出現三次,找出出現一次的數。
- 假設x和y都是整數,得到其中較小的那個。
y^( (x^y)& -(x<y) ) n
- 將一個int型的數的奇偶位互換,例如6的2進位為0110, 第一位與第二位互換,第三位與第四位互換,得到1001,輸出應該為9 。
((n<<1)&(0xAAAA))|((n>>1)&(0x5555)) n
- 給出兩個正整數a和b, 求他們的和, 但不能使用任何數學運算符。
推薦閱讀:
※【雲棲大會】阿里雲聯合中科院量子創新研究院發布量子計算雲平台
※如何切割出音頻文件中的音樂段落與人聲段落?
※PFC5.0中的Range演算法