posts - 495,  comments - 11,  trackbacks - 0

          原題如下:用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 閱讀(96) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 山阳县| 金川县| 柳林县| 德清县| 体育| 自治县| 安乡县| 沙田区| 德兴市| 当雄县| 本溪市| 靖江市| 新密市| 凌云县| 天水市| 广河县| 华坪县| 东源县| 高安市| 鞍山市| 庄河市| 六盘水市| 定安县| 资溪县| 昌黎县| 开江县| 德安县| 高清| 大田县| 昌吉市| 铅山县| 德昌县| 来安县| 沁水县| 宁陵县| 古浪县| 伽师县| 贵南县| 东乌珠穆沁旗| 徐汇区| 木兰县|