原題如下:用1、2、2、3、4、5這六個數字,用java寫一個程序,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"與"5"不能相連。
解題思路:
很明顯,這是一個遞歸算法。我們可以排列將這6個數按從小到大的順序排一下,如果是1,2,3,4,5,6,那么會有1*2*3*4*5*6=6!=720個遞增的數。但如果是1,2,2,3,4,5,那么在這720個數中一定會有相同的數對出現(由于在這6個數中只有兩個數兩同,也就是說,如果有重復的數,那么一定是一對數,如122345會出現兩次)。
排列的基本規則是分步進行。也就是說,要排列上面6個數,首先應該選擇第一個數,這第一個數可以選擇這6個數中的任意一個,如選擇1.第二步是選擇第二個數,這第二個數不能再選擇已經選過的數,如1.因此,它只能從后面5個數中選擇。如選擇2。以此類推。
我們也可以在程序中模擬這一過程。源程序如下:
public class test1 {
???? private int[] numbers = new int[] { 1, 2, 3, 3, 4, 5 };
???? public int n;
???? private String lastResult = "";
???? private boolean validate(String s) {
????????? if (s.compareTo(lastResult) <= 0)
?????????????? return false;
????????? if (s.charAt(2) == '4')
?????????????? return false;
????????? if (s.indexOf("35") >= 0 || s.indexOf("53") >= 0)
?????????????? return false;
????????? return true;
???? }
???? public void list(String index, String result) {
????????? for (int i = 0; i < numbers.length; i++) {
?????????????? if (index.indexOf(i + 48) < 0) {
????????????????????? String s = result + String.valueOf(numbers[i]);
????????????????????? if (s.length() == numbers.length) {
?????????????????????????? if (validate(s)) {
??????????????????????????????? System.out.println(s);
??????????????????????????????? lastResult = s;
??????????????????????????????? n++;
?????????????????????????? }
????????????????????????? break;
????????????????????? }
????????????????????? list(index + String.valueOf(i), s);
?????????????? }
????????? }
???? }
???? public static void main(String[] args) {
????????? test1 t = new test1();
????????? t.list("", "");
????????? System.out.println("總數:" + t.n);
???? }
}
其中list函數是這個算法的核心函數。index參數表示已經選擇過的數,用numbers數組的索引表示。如index="012",表示numbers的前三個數已經被選擇,也表示應該選擇第四個數了,而這第四個數應該從后三個數中選擇。result參數表示臨時的數字組合(這個數字組合最多是5個數字,因為,如果到了6個數字,就表示已經有一個結果產生了)。在默認情況下index和result的值都是""。
在validate中使用了 if (s.compareTo(lastResult) <= 0)進行判斷,由于按這種方法進行排列,如果這6個數是遞增給出的,那么排列的結果一定是遞增的,但上述的6個數其中第2和第3個位置上都是2,因此,如果出現了上一個結果不小于當前結果的情況,一定是有重復了,因此,要將這部分數過濾出去。
使用1, 2, 2, 3, 4, 5的測試結果
122345
122543
123245
123254
123425
123452
125234
125243
125423
125432
132245
132254
132425
132452
132524
132542
142325
... ...
... ...
542313
542331
543123
543132
543213
543231
543312
543321
總數:118
使用1, 3, 3, 3, 4, 5的測試結果
133345
313345
315433
331345
331543
333145
333154
333415
333451
343315
345133
433315
451333
513334
513343
513433
541333
543133
543313
543331
總數:20
posted on 2009-09-03 01:39
jadmin 閱讀(95)
評論(0) 編輯 收藏