輸入乙個字串,列印出該字串中字元的所有排列。
例如輸入字串abc,則輸出由字元a、b、c 所能排列出來的所有字串
abc、acb、bac、bca、cab 和 cba。
解法一、遞迴實現
從集合中依次選出每乙個元素,作為排列的第乙個元素,然後對剩餘的元素進行全排列,如此遞迴處理,從而得到所有元素的全排列。以對字串abc進行全排列為例,我們可以這麼做:以abc為例
**可如下編寫所示:
void calcallpermutation(char* perm, int from, int to)
if (from == to)
else
}}
解法
二、字典序排列
首先,咱們得清楚什麼是字典序。根據維基百科的定義:給定兩個偏序集a和b,(a,b)和(a′,b′)屬於笛卡爾集 a × b,則字典序定義為
(a,b) ≤ (a′,b′) 當且僅當 a < a′ 或 (a = a′ 且 b ≤ b′)。
所以給定兩個字串,逐個字元比較,那麼先出現較小字元的那個串字典順序小,如果字元一直相等,較短的串字典順序小。例如:abc < abcd < abde < afab。
那有沒有這樣的演算法,使得
答案是肯定的:有,即是stl中的next_permutation演算法。
在了解next_permutation演算法是怎麼乙個過程之前,咱們得先來分析下「下乙個排列」的性質。
現在的問題是:找到x和y。怎麼找到呢?咱們來看乙個例子。
比如說,現在我們要找21543的下乙個排列,我們可以從左至右逐個掃瞄每個數,看哪個能增大(至於如何判定能增大,是根據如果乙個數右面有比它大的數存在,那麼這個數就能增大),我們可以看到最後乙個能增大的數是:x = 1。
而1應該增大到多少?1能增大到它右面比它大的那一系列數中最小的那個數,即:y = 3,故此時21543的下乙個排列應該變為23***,顯然 ***(對應之前的b』)應由小到大排,於是我們最終找到比「21543」大,但字典順序盡量小的23145,找到的23145剛好比21543大。
由這個例子可以得出next_permutation演算法流程為:
next_permutation演算法
步驟(二找、一交換、一翻轉)
還是拿上面的21543舉例,那麼,應用next_permutation演算法的過程如下:
翻轉541
bool calcallpermutation(char* perm, int num)
// 已經找到所有排列
if (i < 0)
int k;
//②找到排列中第i位右邊最後乙個比ai 大的位置j,y = aj
for (k = num - 1; (k > i) && (perm[k] <= perm[i]); --k)
//③交換x,y
swap(perm[i], perm[k]);
//④把第(i+ 1)位到最後的部分翻轉
reverse(perm + i + 1, perm + num);
return true;
}
然後在主函式裡迴圈判斷和呼叫calcallpermutation函式輸出全排列即可。
解法總結
由於全排列總共有n!種排列情況,所以不論解法一中的遞迴方法,還是上述解法二的字典序排列方法,這兩種方法的時間複雜度都為o(n!)。
1、已知字串裡的字元是互不相同的,現在任意組合,比如ab,則輸出aa,ab,ba,bb,程式設計按照字典序輸出所有的組合。
分析:非簡單的全排列問題(跟全排列的形式不同,abc全排列的話,只有6個不同的輸出)。 本題可用遞迴的思想,設定乙個變數表示已輸出的個數,然後當個數達到字串長度時,就輸出。
//假設str已經有序
void perm(char* result, char *str, int size, int respos)
}} 2、如果不是求字元的所有排列,而是求字元的所有組合,應該怎麼辦呢?當輸入的字串中含有相同的字串時,相同的字元交換位置是不同的排列,但是同乙個組合。舉個例子,如果輸入abc,它的組合有a、b、c、ab、ac、bc、abc。
3、寫乙個程式,列印出以下的序列。
(a),(b),(c),(d),(e)........(z)
(a,b),(a,c),(a,d),(a,e)......(a,z),(b,c),(b,d).....(b,z),(c,d).....(y,z)
(a,b,c),(a,b,d)....(a,b,z),(a,c,d)....(x,y,z)
(a,b,c,d,.....x,y,z)
字串的排列 全排列
輸入乙個字串,按字典序列印出該字串中字元的所有排列。例如輸入字串abc,則列印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。輸入乙個字串,長度不超過9 可能有字元重複 字元只包括大小寫字母。使用itertools中的permutations,可以實現全排列 ...
遞迴 字串全排列 全排列
在高中階段我們已經通過大量的習題了解了排列和組合。但是有時候我們研究的不是由排列和組合算出來的數字,研究的是生成排列和組合。即,把集合中元素所有的排列和組合全部列出來,然後研究這些序列的性質。今天我用兩種方法講一下如何生成排列。注意我們這裡涉及的順序都是序列的字典序。序列的字典序 設有兩個序列,第乙...
字串全排列
依次選出每乙個字元元素,作為排列的第乙個元素,然後對剩餘的元素進行全排列,如此遞迴處理,從而得到所有元素的全排列。以對字串abc進行全排列為例,我們可以這麼做 固定a,求後面bc的排列 abc,acb,求好後,a和b交換,得到bac 固定b,求後面ac的排列 bac,bca,求好後,c放到第一位置,...