C 實現序列的全排列

2021-08-07 09:29:58 字數 2593 閱讀 3683

c++ stl中提供了std::next_permutation與std::prev_permutation可以獲取數字或者是字元的全排列,每次函式呼叫獲取下一次排列結果。

嘗試自己也實現了一下,功能跟庫函式不同。

#include using namespace std;

void output(char* buff, int len)

cout << endl;

}/* 思路:序列的全排列,就是從其中順序調出乙個元素作為第乙個元素,將剩餘的元素做全排列。

* 也就是把第乙個元素,和後續每個元素做一次交換,把第乙個元素以後的序列做全排列。全排列的結果和第乙個元素合起來就是全排列的結果。

* 其實就是遞迴。

* 引數說明:buff是總序列的頭指標;

* n是總序列的長度。這兩個其實都是為了遍歷和列印的方便。

* walkindex 是子串行的第乙個元素的位置。如果是第一次遍歷,walkindex就是0,也就是全序列的全排列;

* walkindex 為1就表示從buff的第二個元素開始的子串行的全排列。

* 說明:每個迴圈中有兩個swap。第乙個表示把子序列的頭元素依次跟第i個元素交換;然後生成子串行(walkindex後的序列)的全排列;然後恢復(再一次呼叫swap).

* 必須恢復,是因為思路是「順序調出每乙個元素作為第乙個元素」,如果子串行的全排列結束後不恢復,那下一次for迴圈就拿不到正確的元素了。

* 比如原始序列為 1 2 3 4,最外層遍歷先把1和1交換(相當於沒交換),得到子串行2 3 4的全排列,和1組成 6 組結果;

* 然後應該把1和2交換,2在第乙個元素位置,子串行是 1 3 4,在計算這個子串行的全排列,和2 組成6組結果;

* 這時必須恢復1和2原來的順序,才能讓1和3交換做下一次的排序,也就是計算子串行 1 3 4後,必須再一次swap恢復出廠設定。

* */

void permutations(char* buff, int n, int walkindex)

for(int i = walkindex; i < n; i++) }

int main() ;

permutations(anagrams, 4, 0);

cout<<"全排列後,anagrams會恢復到最初狀態:" << endl;

output(anagrams, 4);

return 0;

}

補充:

這兩天看帖子,發現有人對上面的流程有比較清晰的描述,演算法實現也是一模一樣的。轉錄其描述部分如下:

###中心思想:

設r=是要進行排列的n個元素,ri=r-.

perm(x)表示在全排列perm(x)的每乙個排列前加上字首ri得到的排列。

(1)當n=1時,perm®=®,其中r是集合r中唯一的元素;

(2)當n>1時,perm®可由(r1)+perm(r1),(r2)+perm(r2),…,(rn)+perm(rn)構成。

那麼具體程式要怎麼實現呢?我們來個實際的例子,假設有一數列1,2,3,4

那麼1,2,3,4的全排列

perm()=1perm()+2perm()+3perm()+4perm(1,2,3)

那麼我們只要將每個數,與第乙個數交換不就可以得到下乙個序列了嗎?

比如第乙個與第二個數交換,那麼不就得到2 了,接下來我們用乙個實際的例子說明該程式是怎樣執行的

####具體演算法流程:

數列: 第乙個與第乙個交換

可以得到1 將序列放進perm函式遞迴,然後

——遞迴

數列第乙個與第乙個交換

得到2 ,輸出1,2,3 (此時low=high,因為序列只有一位數,因此輸出列表list)

數列第乙個與第乙個交換回來,結果仍然是

數列第乙個與第二個交換

得到3,輸出1,3,2

又第乙個與第二個交換回來,變回

—–遞迴完畢序列恢復原狀

數列: 第乙個與第二個交換

可以得到2,

——遞迴

數列第乙個與第乙個交換

得到1 ,輸出2,1,3

數列第乙個與第乙個交換回來,結果仍然是

數列第乙個與第二個交換

得到3,輸出2,3,1

又第乙個與第二個交換回來,變回

—–遞迴完畢

序列第乙個與第二個交換

序列恢復原狀

數列: 第乙個與第三個交換

可以得到3,

——遞迴

數列第乙個與第乙個交換

得到1 ,輸出3,1,2

數列第乙個與第乙個交換回來,結果仍然是

數列第乙個與第二個交換

得到2,輸出3,2,1

又第乙個與第二個交換回來,變回

—–遞迴完畢

序列第乙個與第二個交換

序列恢復原狀

演算法可以簡單地寫作

perm()=1perm()+2perm()+3perm()

perm()=2perm()+3perm()

perm()=1perm()+3perm()

perm()=1perm()+2perm()

C 實現全排列

總時間限制 1000ms 記憶體限制 65536kb 描述給定乙個由不同的小寫字母組成的字串,輸出這個字串的所有全排列。我們假設對於小寫字母有 a b y z 而且給定的字串中的字母已經按照從小到大的順序排列。輸入輸入只有一行,是乙個由不同的小寫字母組成的字串,已知字串的長度在1到6之間。輸出輸出這...

C 實現全排列

給定乙個陣列,求這個陣列的全排列。列如 a 對陣列a求全排列 結題思路 將a陣列中的元素依次放在第乙個位置然,對剩下的元素進行全排列。剩下元素全排列依然是,將剩下的元素依次放在第乙個位置,對剩下的元素進行全排列。直到剩下的元素個數為乙個時,排列結束。這裡我給出固定元素1,對元素2 3 4進行全排列的...

全排列的實現(C)

找工作,筆試經常會出現乙個題,怎樣生成乙個集合內所有元素的全排列。剛開始的時候沒有覺得這是乙個難的問題。其實,當寫在試卷上,真的不太會,作答的過程感覺心裡沒有什麼底。回來後,查了一些資料,看了一些書,對這個問題有一定的認識,舉乙個例去清晰一下題目的意思,例子為 字符集的全排列 123,132,312...