陣列,字串全排列演算法分析(字典序生成法)

2021-07-16 13:18:26 字數 1781 閱讀 9952

先看乙個題:

題目描述

輸入乙個字串,按字典序列印出該字串中字元的所有排列。例如輸入字串abc,則列印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 結果請按字母順序輸出。

輸入描述: 輸入乙個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。

就是輸入乙個字串,按字母順序輸出全排列後的字串。下面說乙個字典序方法。

先用乙個比較簡單的數字字串舉例子,原理相同。假設我們給定乙個數字字串87632491,我們找出下乙個比他大的字典序列。

1.從最右邊往左邊掃瞄,找到第乙個數字符合如下標準,該數字的右鄰比他大。從上面的例子我們能夠看到,該數字是4,下標是i=5(從0開始);

2.從上面找到的陣列下標i開始從左向右掃瞄,找到i右邊比4大的元素中最小的乙個。很容易的就能夠找到,是1,下標j=7;

3.交換i和j位置的元素。交換後是87632194。

4.逆序i+1到n位置的元素。逆序後是87632149

5.處理後的字串就是我們要找的下乙個字典序中的字串。回到第一步繼續迭代即可找到所有排列。

public arraylistpermutation(string str) 

//將字串轉成位元組陣列,方便排序

char a = str.tochararray();

//按字母表中的位置排序,如果忽略此步,會導致找到的全排列有所丟失。即給定字串是bac,如果不重新排列成abc,那麼abc-bac之間的字典序字串會丟失

arrays.sort(a);

while (true)

//找到符合的元素j後,反向掃瞄,尋找比j元素大的中最小的乙個。其實整個地方比較簡單,我們在第一次for迴圈時,找到j,說明從n到j,即陣列從右向左一直到j,是遞增的,否則不會找到j。所以我們只需要從陣列最右端先左掃瞄即可找到第乙個比j大的,即使符合要求的。

for (i = a.length-1; i>0&&a[i]<=a[j]; i--);

int k = i;

//找到j和k元素後,交換兩個元素,

char b = a[j];

a[j] = a[k];

a[k] = b;

//上面的工作我們只是找到了j位置的元素,j+1到n位置的元素還是乙個遞增的,不符合字典序,下面是逆序的過程

for (int l = j+1; l < (a.length+j)/2+1; l++)

//全部處理完,找到所需要的字典序,在找到的字典序陣列基礎上,再去找下乙個字典序

}}

更多的方法,待更新。

後續更新————————————————–

遞迴的方法

// 遞迴的方法

static

public arraylistpermutation1(string str)

char a = str.tochararray();

arrays.sort(a);

swap(a, 0, res);

// collections.sort(res);

for (string s : res)

return res;

}static

void swap(char a, int start, arraylistres) else }}

}

good good study,day day up。

演算法練習 字串的全排列 字典序排列

輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a b c 所能排列出來的所有字串abc,acb,bac,bca,cab,cba。又是乙個經典問題,最容易想到的解決方法仍然是窮舉 我實在是太愛窮舉法了,每當被問到演算法問題不知道如何解決的時候,總可以祭出窮舉大旗,從而多爭...

全排列演算法的字典序排列

之前在中描述了全排列演算法的遞迴解法,這裡再說一種演算法 字典序排列。字典序排列就是按照字典a z,1 9的順序給出字串的順序全排列,例如abc的全排列就是從abc一直排到cba。那麼給定乙個字串,怎麼找出恰好大於該字串的下乙個排列呢?我們考慮如下的步驟 1 假設字串為p1p2 pn,我們從後往前尋...

字典序輸出全排列演算法

請編寫程式輸出前nnn個正整數的全排列 n 10n 10n 10 並通過9個測試用例 即nnn從1到9 觀察nnn逐步增大時程式的執行時間。輸入給出正整數nnn 10 10 10 輸出1到nnn的全排列。每種排列佔一行,數字間無空格。排列的輸出順序為字典序,即序列a1,a2,ana 1 a 2 a ...