wangflood

          精心維護一個技術blog,為了工作,也是愛好。

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            14 Posts :: 19 Stories :: 8 Comments :: 0 Trackbacks
          前些日子在群里討論,有一個哥們出一道題:5,6,7,8,9,10按順序插入+-*/和括號,得到結果2000.
          大家的先沉默了一會,二分鐘后,有人說這題沒意思。呵呵。口算還是有點難的。于是我說,可以寫個程序試一試。結果,花了三個小時,寫完了
          import java.util.HashSet;
          import java.util.Iterator;
          import java.util.Set;

          /**
           * 
          @author Sam Wang
           * 
          @since Mar 22, 2011
           
          */
          public class Demo {

              
          public static void main(String[] args) {

                  
          double[] arr = { 5678910 };
                  
          double[] arrTemp = null;
                  
          int random = 0;
                  
          double last = 0;
                  StringBuffer sb 
          = null;
                  Set
          <String> results = new HashSet<String>();

                  
          for (int i = 0; i < 100000; i++) {
                      arrTemp 
          = arr.clone();
                      shuffle(arrTemp);
                      sb 
          = new StringBuffer();
                      sb.append(arrTemp[
          0]);
                      
          for (int j = 1; j < arrTemp.length; j++) {
                          random 
          = (int) (Math.random() * 4);
                          
          switch (random) {
                          
          case 0:
                              sb.append(
          "+").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1+ arrTemp[j];
                              
          break;
                          
          case 1:
                              sb.append(
          "-").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1- arrTemp[j];
                              
          break;
                          
          case 2:
                              sb.append(
          "*").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1* arrTemp[j];
                              
          break;
                          
          case 3:
                              sb.append(
          "/").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1/ arrTemp[j];
                              
          break;

                          
          default:
                              
          break;
                          }
                      }

                      last 
          = arrTemp[arrTemp.length - 1];
                      System.out.println(last);
                      
          if (last == 2000) {
                          sb.append(
          "=2000");
                          results.add(sb.toString());
                      }
                  }

                  
          for (Iterator<String> it = results.iterator(); it.hasNext();) {
                      String item 
          = it.next();
                      System.out.println(item);

                  }
              }

              
          /**
               * 
          @param arrTemp
               * 
          @return void 打亂數組元素順序。
               
          */
              
          private static void shuffle(double[] arrTemp) {
                  
          int index = 0;

                  
          for (int i = 0; i < arrTemp.length; i++) {
                      index 
          = (int) (Math.random() * arrTemp.length);
                      swap(arrTemp, i, index);
                  }
              }

              
          /**
               * 
          @param arrTemp
               * 
          @param i
               * 
          @param index
               *            交換數據元素
               
          */
              
          private static void swap(double[] arrTemp, int i, int index) {
                  
          double temp = arrTemp[i];
                  arrTemp[i] 
          = arrTemp[index];
                  arrTemp[index] 
          = temp;
              }

          }
          有兩個技巧:在不確定是+-*/哪種情況下,可以random一下,多for幾次,那么這幾種情況大致上可以照顧到。
                                ()在算法里面的體現是,使用()我發現,數字的前后順序可以混亂。打印出結果不行的話再刪除不遲。
          打印結果:
          9.0*8.0-7.0*6.0+10.0*5.0=2000
          8.0*9.0-7.0*6.0+10.0*5.0=2000
          7.0*8.0+9.0*6.0+10.0*5.0=2000
          打印出來的效果不太好,我組織一下:
          5*(6*(-7+8*9)+10)=2000;
          5*(6*(7*8+9)+10)=2000;
          如果,不允許取負數的話,當然就只有一個結果了。

          有點疑惑,為什么Collection.shuffle()可以,Array.shuffle()卻不提供。

          當然,算法肯定有可以改進的地方。



          posted on 2011-03-29 12:31 wangflood 閱讀(369) 評論(1)  編輯  收藏

          Feedback

          # re: 56789+-*/() 2000 2011-03-30 13:12 wangflood
          趙靖 5:47:53 AM
          這題用逆波蘭(后綴)式再枚舉即可,然后轉化為帶括號的中綴式
          趙靖 5:48:17 AM
          就可以繞過括號,這樣就變成一道體力活了
          蕎葉 5:52:07 AM
          哈哈。
          蕎葉 5:52:49 AM
          那晚,我寫了三個小時。
          趙靖 5:53:27 AM
          完全做出來三個小時不算多,但是有正確的方向要堅定的多
          趙靖 5:54:51 AM
          數字是排定的,符號插入其中,再構造圖求路徑的話就更清晰了
          蕎葉 5:55:04 AM
          http://www.aygfsteel.com/wangflood/articles/Demo.html
          蕎葉 5:55:06 AM
          呵呵。
          趙靖 5:56:39 AM
          這樣做法可能是錯誤的,設想如果(5+6)*(7+8)+9+10這個順序是shuffle不出來的
          趙靖 5:57:21 AM
          后綴應為56+78+*9+10+
          趙靖 5:57:46 AM
          要去掉括號,后綴是一個絕佳的選擇
          蕎葉 5:58:01 AM
          不允許56這樣的組合。
          趙靖 5:58:13 AM
          我寫的是后綴式
          蕎葉 5:58:18 AM
          shuffle是把[5,6,7,8,9,10]的前后順序弄亂。
          蕎葉 5:58:27 AM
          發來看看啊。
          蕎葉 5:58:35 AM
          不懂后綴式是什么意思。、
          趙靖 5:58:52 AM
          逆波蘭式呀
          趙靖 5:59:08 AM
          就是后根遍歷表達式
          趙靖 6:01:35 AM
          看看你的程序能不能找到184
          蕎葉 6:02:03 AM
          為什么要找到184
          趙靖 6:02:20 AM
          這個說明你shuffle是不能表達括號的優先級的
          蕎葉 6:03:48 AM
          shuffle,比括號得到了更多的結果。
          蕎葉 6:03:59 AM
          但括號可以做到的,shuffle都給辦到。
          趙靖 6:04:31 AM
          你怎么表達這種括號呢(5+6)*(7+8)
          趙靖 6:04:52 AM
          shuffle 去掉括號看看
          蕎葉 6:05:22 AM
          對噢。
          蕎葉 6:06:35 AM
          可以這樣,5+6)*(7+8)
          算出5+6后,就是[11,7,8,9,10]再次shuffle
          趙靖 6:06:51 AM
          那算法也太猥瑣了些
          蕎葉 6:06:56 AM
          哈哈。就期望能算出第二個結果來。
          蕎葉 6:06:59 AM
          我也這么覺得啊。
          趙靖 6:09:47 AM
          這個式子的通用格式是

          5678910
          abcdef
          然后吧abcde查到合適的位置去,其中至少f是最后面的
          如56+67+*8+9+10+就表達了(5+6)*(7+8)+9+10
          趙靖 6:10:19 AM
          后綴計算是最快的,僅僅需要一個棧
            回復  更多評論
            


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


          網站導航:
           
          主站蜘蛛池模板: 桐梓县| 维西| 育儿| 祁东县| 嘉义县| 庄河市| 洮南市| 潮州市| 昭苏县| 石楼县| 肃南| 元谋县| 灵川县| 泰和县| 科技| 张家界市| 利辛县| 类乌齐县| 渭源县| 枣庄市| 澄城县| 新沂市| 贵州省| 大连市| 桂阳县| 萨嘎县| 闸北区| 托里县| 同德县| 明星| 石家庄市| 竹溪县| 汨罗市| 乐山市| 英德市| 新宁县| 阜南县| 太仆寺旗| 阜城县| 清水县| 文登市|