n bits 依次變一位排列的演算法

2022-07-18 22:51:16 字數 2257 閱讀 4998

題目要求對長為n的bit陣列輸出所有0、1組合,相鄰兩個只有乙個bit發生變化。如果n=2,則可以有下面的輸出:

0000

0101 11

10 10

11

那麼左邊的是正確的,右邊的不正確,因為01和10之間差了兩位。

首先想到的辦法是如下遞迴,設f(n)返回乙個長度為n的bit陣列,並且陣列按照題目要求的那樣排列。那麼f(n+1)可以如下獲得:

f(n+1)= 連線

由於f(n)的元素滿足要求,其倒排肯定也滿足要求。唯一要證明的是接頭的地方是否滿足要求。容易看到f(n)的最後乙個元素必然等於f(n)倒排的第乙個元素,因此連線處也是滿足要求的。

演算法如下:

這個演算法有個缺點是需要生成很多臨時陣列,並且最後需要乙個長度為2的n次方的大陣列來儲存結果。能不能找到一組就立刻輸出,不儲存呢?回到最初的遞迴表示式:

f(n)= 並上

可以得到如下樹結構:

注意到第三層的11和10是倒過來的,按照原始演算法下先是10再是11。由此我們想到有兩種遞迴:

f(n)= 並上 先0後1

f(n)= 並上 先1後0

需要結合起來,因此有如下的表示式:

f(n,bitflag)= 並上

那麼x是0還是1呢,bitflag』又該怎麼變化呢?

顯然bitflag為0的時候表示正常,為1表示需要翻轉。正常情況先0後1,翻轉情況先1後0.

那什麼時候需要翻轉?注意到如果父節點包含奇數個1則需要翻轉。因為演算法保證f(n-1)的序列滿足相鄰數隻差乙個bit的需求,那麼要想它的下一層是相連線的,必須要求相鄰的兩個子樹是映象。也就是說如果i子樹翻轉了,i+1就不能翻轉。00顯然不翻轉,故01翻轉,11不翻轉,10翻轉。

因此演算法表示式為:

f(n,bitflag)= 並上 bitflag==0

f(n,bitflag)= 並上 bitflag==1

**如下,if bit0那個可以壓縮。但是為了方便理解,就不壓縮了:

line=0;

def changeonebit1(a, n, bit0):

global line;

if(n==0):

line=line+1

print str(line)+':'+str(a);

else:

if(bit0==0):

a[n-1]=0;

changeonebit1(a,n-1,bit0 ^ a[n-1]);

a[n-1]=1;

changeonebit1(a,n-1,bit0 ^ a[n-1]);

else:

a[n-1]=1;

changeonebit1(a,n-1,bit0 ^ a[n-1]);

a[n-1]=0;

changeonebit1(a,n-1,bit0 ^ a[n-1]);

執行結果如下:

1:[0, 0, 0, 0]

2:[1, 0, 0, 0]

3:[1, 1, 0, 0]

4:[0, 1, 0, 0]

5:[0, 1, 1, 0]

6:[1, 1, 1, 0]

7:[1, 0, 1, 0]

8:[0, 0, 1, 0]

9:[0, 0, 1, 1]

10:[1, 0, 1, 1]

11:[1, 1, 1, 1]

12:[0, 1, 1, 1]

13:[0, 1, 0, 1]

14:[1, 1, 0, 1]

15:[1, 0, 0, 1]

16:[0, 0, 0, 1]

總結一下,這個題目其實只是資料排列的乙個小小的變化,但是需要透徹的理解遞迴的本質,寫出遞迴表示式,並進一步描繪遞迴空間樹,找出節點的規律,才能進一步實現演算法。 technorati tags: 演算法,遞迴

一位原碼的乘法規則 原碼一位乘法的實現演算法

原碼一位乘法的實現演算法 一 用原碼實現乘法運算是十分方便的。原碼表示的兩個數相乘,其乘積的符號為相乘兩數符號的異或值,數值則為兩數絕對值之積。假定 x 原 xsx1 x2 xn y 原 ysy1y2 yn 則 x y 原 x 原 y 原 xs ys x1x2 xn y1 y2 yn 結果是把符號位...

群裡一位老大貼的排序演算法

這是我qq群裡乙個老大的貼的排序演算法,感覺比較經典,所以就貼到這了.void swap int a,int b void sort int arr,int beg,int end swap arr l arr beg sort arr,beg,l sort arr,r,end void sort2...

mysql在表的某一位置增加一列的命令

如果想在乙個已經建好的表中新增一列,可以用諸如 alter table t1 add column addr varchar 20 not null 這條語句會向已有的表t1中加入一列addr,這一列在表的最後一列位置。如果我們希望新增在指定的一列,可以用 alter table t1 add co...