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...