字串全排列 非遞迴實現

2021-08-14 04:45:39 字數 1915 閱讀 4793

乙個演算法命題:給定字串s[0…n-1],設計演算法,列舉s的全排列。如:123,全排列就是:123,132,213,231,312,321

由123的全排列:123,132,213,231,312,321可知,這個全排列大小是有序的。也就是說,從最小的開始排列,每次只找比當前排列大一點的序列即可,這也是核心。

起點:字典序最小的排列,例如12345

終點:字典序最大的排列,例如54321

乙個演進:

逐位考察哪個能增大:乙個數右面有比它大的數存在,它就能增大。

那麼最後乙個能增大的數是——x = 1,1應該增大到多少?

增大到它右面比它大的最小的數——y = 3

應該變為23***。 顯然,***應由小到大排:145 , 得到23145

步驟:後找、小大、交換、翻轉——

後找:字串中最後乙個公升序的位置i,即:s[k]>s[k+1](k>i),s[i]

查詢(小大):s[i+1…n-1]中比ai大的最小值sj;

交換:si,sj;

翻**s[i+1…n-1]; 為什麼要翻轉?因為交換操作後,s[i+1…n-1]一定是降序的

以上是官話,比較難理解,我的理解如下

過程化:整理成演算法語言

步驟:後找、小大、交換、翻轉——

後找、查詢:從倒數第二位開始作為基礎位置,找基礎位置後的比基礎位置上的數大的且最小的數

交換:交換基礎位置上的數 和 找到的比基礎位置大的最小的數

翻**將基礎位置之後的數反轉。因為此時基礎位置後的數一定是降序的,要讓它成為公升序

/*有序序列的全排列演算法*/

void allsequence(char s)else

} }/**

* 獲得字串序列中兩個交換位置,這兩個位置上的數交換後,可以增大該字串序列。這裡獲得的就是能最小增大的兩個交換位置。

* 例如:1342,那麼找兩個位置上的數交換後能讓他增大。那基礎位置就可以從倒數第二個數開始,然後從基礎位置往後找,

* 若找到比基礎位置上的數大的數,那此時交換兩個數就能增大這個序列。並且要找到比基礎位置上的數大並且是所有比它大的最小的數

* @param str

* @return 返回的int[2]陣列元素。0位置元素記錄交換的左邊位置,1位置元素記錄交換的右邊位置

*/int getswapfromandtoindex(char str)

}if(++afterbasis > str.length - 1)else

}} return null; }

void swapchar(char s, int i, int j)

/**反轉。把字元陣列從from位置開始後的數反轉*/

void revertstr(char str, int from)

for(int i = from; i < (str.length + from)/2;i++) }

public static void main(string args)

注:以上**是放在類strremove中,所有strremove s1 = new strremove()來準備呼叫方法

最終結果:

123

132213

231312

321-------------------------------------

1223

1232

1322

2213

2231

2312

2321

3122

3221

相對於遞迴實現的全排序演算法稍微複雜些,但是深度不大。非遞迴實現的恰好免疫有重複序列的全排序,不會重複;例如**中測試的1223序列,不會產生多餘的全排序

另一實現:字串全排列-遞迴實現

C 演算法 字串全排列 非遞迴 非遞迴

字串的全排列是面試中相對而言必要重要的演算法,有兩種實現方法 遞迴,非遞迴 替換點 從字串的最後一位開始,找到第乙個逆序的字串,如 54312 那麼從後向前第乙個逆序為12,那個1就是替換值,替換值得位置就是替換點。非遞迴演算法思想 對於乙個字串4231,這個字串中排列組合中1234是最小的數,43...

遞迴 字串全排列 全排列

在高中階段我們已經通過大量的習題了解了排列和組合。但是有時候我們研究的不是由排列和組合算出來的數字,研究的是生成排列和組合。即,把集合中元素所有的排列和組合全部列出來,然後研究這些序列的性質。今天我用兩種方法講一下如何生成排列。注意我們這裡涉及的順序都是序列的字典序。序列的字典序 設有兩個序列,第乙...

字串的全排列詳解,遞迴 非遞迴

輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba 首先,我們固定第乙個字元a,求後面兩個字元bc的排列 當兩個字元bc排列求好之後,我們把第乙個字元a和後面的b交換,得到bac,接著我們固定第乙...