第七十題(字串的全排列)

2021-06-22 16:10:22 字數 1854 閱讀 5954

70.給出乙個函式來輸出乙個字串的所有排列。

分析:採用遞迴實現,從字串中依次選出乙個元素做為全排列的第乙個元素,然後求剩下的字元的全排列,採用和當前字串第乙個字元進行交換的方式來將字串中的某個字元放到第一位。

需要注意的是,對於重複的字元要判斷決定要不要進行交換操作,避免重複的全排列結果。

位置current的字元和位置i的字元進行交換時,有兩種可能導致重複的情況:

1.當位置current和位置i字元相同時,不進行交換。例如current指向字串

「abcbd」第乙個b,i指向第二b,交換後排序相同

2.位置current和位置i字元不相同,但是current和i之間有和i位置相同的字元,不進行交換。例如current指向字串「abcdc」的a,i指向最後乙個c,因為之前a已經和第乙個c交換過,並且在子遞迴過程中,交換之後的a又和最後乙個c進行了交換,已經產生「cbcda」這樣的排列,所以這裡也不進行交換。

c++**:

void swap(char& c1, char& c2)

bool needswap(char *str, int current, int i) //重複判斷

void helper(char* str, int current, int length)

for (int i = current; i

上面給出的是遞迴的做法,這裡再拓展一下,講一講 stl演算法中next_permutation的思想:字典排序演算法。從字典順序最小的一種排列開始,我們每次獲得字典序剛好比前乙個排列大的排列,直到得到字典序最大的排列時,就得到了所有的結果。

以字串"abc"為例,"abc"是字典序最小的排列,所有情況按字典序排列為"abc","acb","bac","bca","cba","cab"

具體演算法為:

1.字串進行排序,得到字串的最小字典序排列(c0c1c2...cn),ci<=ci+1。  

2.從後往前,找到一對相鄰的公升序元素cici+1,(ci

3.從字串結束位置到位置i遍歷,找到比ci大的元素cj,交換cj的位置

4.將ci+1到cn所有的字元逆序,這樣得到的排列剛好比之前的字典序大(因為轉換後ci+1

5.重複3,4,5過程直到字典序最大

c++**:

void quicksort(char* str, int len)

for (; j>i; j++)

if (str[i] > c)

}str[i] = c;

} //非遞迴演算法

void allrangedict(char* str)

}

全部**和測試結果:

#includeusing namespace std;

namespace ms100p_70

bool needswap(char *str, int current, int i) //重複判斷

void helper(char* str, int current, int length)

for (int i = current; i i; j--)

if (str[j] < c)

for (; j>i; j++)

if (str[i] > c)

}str[i] = c;

} //非遞迴演算法

void allrangedict(char* str) }

void test() }

int _tmain(int argc, _tchar* argv)

執行結果:

演算法題 字串的全排列

問題 編寫乙個函式,用它把字串中所有的字元的各種排列形式全部顯示出來,即用給定字元做全排列。如 比如給定字串 hat 函式輸出全排列 tha,aht,tah,ath,hta,hat.演算法如下 void dopermute char in,char out,int used,int length,i...

OJ題 字串的排列 全排列問題

題目描述 輸入乙個字串,按字典序列印出該字串中字元的所有排列。例如輸入字串abc,則按字典序列印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。解法一 c 中本身有全排列的函式 next permutation 標頭檔案函式原型 bool next permu...

CVTE筆試題 字串的全排列

下面我就程式設計題 字串的全排列進行總結 當然,這道題在劍指offer上就有,面試經常出,我以前也做過,但是時間長了,不太熟了,做的時候挺吃力,就在這裡總結一下吧!題目 輸入乙個字串,列印該字串中字元的所有排列,例如輸入abc,則列印出abc,acb,bac,bca,cab,cba。解法一 遞迴 就...