位運算技巧,繼續

2022-03-12 14:09:43 字數 1287 閱讀 4454

o(1)的時間,根據前一組合列舉下一組合

using

system;

namespace

class

program

static

void

combian(

intn,

intk)

intik =(

1<<

k) -1;

while

(ik !=0

)}//輸出空行分隔之

console.writeline();

ik =

next_combination(n, ik);}}

static

intnext_combination(

intn,

intk)

else}}

}

根據k,得到比k大,並且二進位制下有相同個數的』1′,而且是當中最小的數

比如把1011,變成1101

首先,因為1的個數要相同,並且比原數要大,那麼,先要找出右起第一次出現1的位置,對這個數加上1,然後在最右邊補上少了的1就可以了。

找出右起第一次出現1的位置的演算法很簡單,就是(n & -n),這裡的b就是得到這個位置,t就是加了以後的結果,這個應該不難明白,關鍵的,是後面的計算。

後面的計算,主要是針對右邊補1的個數,細心想一下,你就知道,要補的1的個數,等於原數右起第乙個1向左數,連續的1的個數減1,然後,t^k是什麼意思呢?這個就非常有技巧了,它的效果其實和x ^ (x – 1)很類似。

而x ^ (x – 1)的作用,是保留右起第乙個「1」,同時把右起第1個「1」右邊全部變為「1」,類似1101000 -> 1111

逆向過來說,就是k = 1100111,對它 +1後,得到t = 1101000,用這個運算可以得到1111,位數和少掉的1成常數差的關係

事實上,這樣我們變相地得到少掉的1的個數(這個例子中是少了兩個1),我們只需要對運算結果中1的個數減2即可,用》2解決之

不過,在當k最右邊不是1,有若干個0的時候,前乙個步驟得到的數的最右邊,就會有同樣多的0,如何去掉這些0?

這時候,我們最初計算的b,即(n & -n)就太有作用了,只要除以這個b,0就沒有了,最後,就是最右邊應該補上的值,和前面的t求和,或者求並均可。

輸出結果是:

0 1 2

0 1 3

0 2 3

1 2 3

0 1 4

0 2 4

1 2 4

0 3 4

1 3 4

2 3 4

位運算技巧

1.lowbit x 實現 int lowbit int x 這個函式用來求數中二進位制位中最低位的1 完整求法 log2 lowbit x 需要注意的是,答案的範圍是0 30,因為31位是符號位,求出來的值為負數,原因如下 設x 0x8000 0000,那麼設res lowbit x 0x8000...

位運算技巧

數字和1相與 判斷奇偶 x 1 1 奇數 x 1 0 偶數 不用其他空間交換兩值 a a b b a b a a b 或a a b b a b a a b a 0 a a a 0 不用其他空間找陣列中唯一成對的那個數 int b 0 for int i 1 i 10 i int a 10 for i...

位運算技巧

1.或 符號 比較兩個數的每一位,只要有乙個數在這一位上為1,所得的新數在這一位上就為1,否則為0。2.與符號 比較兩個數的每一位,只有兩數這一位同時為1時所得新數為1,否則為0。3.異或 符號 比較兩數的每一位,如果一樣所得新數這一位就是0,不一樣就是1。4.取反 符號 0變1,1變0。5.移位 ...