列印全排列

2021-06-20 01:55:53 字數 1248 閱讀 9177

今天碰到乙個打全排列的問題,仔細研究了一下,用遞迴的思想搞出來了,現在把大概思想貼在下面了:

假設要列印的是a, b , c , d , e , 很明顯應該採用遞迴,遞迴就得有子問題

列印a, b , c , d , e 的問題可以分解成以下幾個子問題

列印a, 列印{

b , c , d , e}的全排列

列印b, 列印{a , c , d , e}的全排列

列印c, 列印{a , b , d , e}的全排列

列印d, 列印{a , b , c , e}的全排列

列印e, 列印{a , b , c , d } 的全排列

這樣就能確定函式的輸入

printpermutation (int a[ ], int len)

} 這裡第乙個要解決的問題是什麼時候輸出列印,如果把列印寫在else裡,由於遞迴的深度不同,就會產生排前面的數列印的次數少,排後面的數列印次數多,最保險的做法是,當len==1時,才列印整個排列,也即是寫在終止操作裡。

但是此時,len=1,並不確定原來一共有幾個數,因此,在函式中加乙個引數k, printpermutation (int a, int k, int len), k是記錄還有k個數要排,一直保持陣列長度len的值不變是為了在列印排列的時候知道什麼時候該終止。 (如果是列印字串的全排列,可以省掉乙個引數,因為字串的結尾是確定的)

第二個問題是當長度為k時,子問題的數量是k個,如何寫成乙個迴圈的形式呢?

最簡單的思路是從i=1:k,依次把把a[i]與a[1]進行交換,然後對後面的k-1個數進行全排列,用程式實現就是

swap(a[1],a[i])   printpermutation(a, k-1, len)

當i個子問題解決完後,還需要 swap(a[1],a[i])交換回來,再解決下乙個子問題,不然,後面的次序就亂了。

理清思路寫程式應該不難, swap(int &a, int &b) 這裡需要加引用

void pintpermutation(int a, int k, int len)

else

} }

對於上面的程式,主要在交換這一句swap(a[len-k],a[len-k+i]);

如果把k的含義改一下,看起來更容易一點printpermutation(a, k, len),如果k的含義是從a[k]到a[len-1]的排列,swap就換成swap(a[k],a[k+i]), 遞迴呼叫中k+1, 遞迴終止條件就變成 k==len-1。

上面只是提供了乙個列印全排列的思想。 

全排列列印

全排列的要求 輸入 字串 abc 輸出 如下圖示,思路1 全排列的遞迴實現核心思想 比如對於字串 abc 第一步 求所有可能出現在第乙個位置的字元即 a,b,c。使用方法 把第乙個字元和後面的b c字元進行交換。第二步 把第乙個字元後面的所有字元仍然看成兩部分,即後面的第乙個字元及除此之外的其他字元...

列印全排列

第一次嘗試 define crt secure no warnings include include 在被交換的元素前面序列中,如果出現了這個元素,那麼就不必交換了 intjudge int arr,int i,int k return1 int stringrank int arr,int k,...

全排列列印

全排列列印 全排列的要求 輸入 字串 abc 輸出 如下圖示,思路1 全排列的遞迴實現核心思想 比如對於字串 abc 第一步 求所有可能出現在第乙個位置的字元即 a,b,c。使用方法 把第乙個字元和後面的b c字元進行交換。第二步 把第乙個字元後面的所有字元仍然看成兩部分,即後面的第乙個字元及除此之...