先看乙個題:
題目描述就是輸入乙個字串,按字母順序輸出全排列後的字串。下面說乙個字典序方法。輸入乙個字串,按字典序列印出該字串中字元的所有排列。例如輸入字串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 ...