看到乙個題目:輸出乙個字串的所有排列。
大致想了一下,覺得需要用到遞迴,而遞迴是我不太擅長的,所以就想練一下。
在知道遞迴之前,容易想到的一種辦法是:
假設字串為s,那麼寫乙個有s.length()層巢狀的迴圈形如:這個方法比較容易實現,演算法也簡單,但是有乙個前提——字串s的長度必須是已知的,否則就會不知道要寫幾層迴圈~~尷尬而且如果字串很長,比如100,就要寫可怕100層迴圈~~
——顯然這不是乙個很好的辦法。
對遞迴有些了解之後,就會想到,這題用遞迴會很合適。
費了很大的勁,寫出了如下**——
結果:
1234 --- 11243 --- 2
1342 --- 3
1324 --- 4
1423 --- 5
1432 --- 6
2341 --- 7
2314 --- 8
2413 --- 9
2431 --- 10
2134 --- 11
2143 --- 12
3412 --- 13
3421 --- 14
3124 --- 15
3142 --- 16
3241 --- 17
3214 --- 18
4123 --- 19
4132 --- 20
4231 --- 21
4213 --- 22
4312 --- 23
4321 --- 24
14行以後是遞迴的應用,也是這段**的核心
遞迴:就是自己呼叫自己。
遞迴是需要結束條件的,要不然就是無盡的迴圈了,在這段**中,結束條件在15行, if (s.length() == 0) 即當傳遞的引數s長度為0時結束遞迴。函式接收的引數為字串s和n,每次在函式內部呼叫自身,即乙個遞迴呼叫,引數為s.substring(1)和 n + s.charat(0)); 每次呼叫的引數都會是引數s的長度減少1,而n增加1,直到結束條件s.length() == 0為真,遞迴結束,列印乙個結果。遞迴會進行s.length()次,而且函式呼叫自身的地方位於迴圈 for (int i = 0; i < s.length(); ++i) 中,所以會列印出s.length()!次結果。這與數學分析的結果是一致的。20行 s = s.substring(1) + s.charat(0); 是必須的,它的作用是使字串平移一位,如s為"1234",執行此句後就變為了"2341",保證每次產生不重複的結果。個人認為:遞迴的優點在於:一些問題用遞迴程式設計時能使思路非常清晰、**簡潔。而缺點同樣很明顯:占用記憶體將很大。乙個例子,求n階乘的兩種方法
體會之。
受東平小同學蠱惑,第一次用writer寫文章,感覺還好。
JAVA遞迴和非遞迴輸出字串的全排列
要輸出字元s從 start,end 間的全排列,只要將s start,end 依次與s start 替換並輸出s從 start 1,end 的全排列即可。遞迴輸出全排列 public static void fullpermutation string s private static void p...
如何輸出字串的所有組合
問題描述 假如字串中所有字元都不重複,如何輸出字串的所有組合。例如 abca,結果應是a,b,c,ab,ac,bc,abc。最容易想到的就是遞迴了,但效率會變得很差,因為棧被呼叫了2 n次方,為了提高效率,可以構造乙個長度為n的01字串,表示輸出結果中是否包含某個字元,例如 001 c,010 b,...
01 輸出字串中字元的所有組合
1 def perm s 2 這裡是遞迴函式的出口,為什麼呢,因為這裡表示 乙個長度為1的字串,它的排列組合就是它自己。3if len s 1 4return s 5 sl 儲存字串的所有可能排列組合 6for i in range len s 這個迴圈,對應 解題思路1 確定字串的第乙個字母是誰,...