java 24點算法實現

 

  最近閒來無事,忽然懷念起小時候和堂兄表姐們常常玩24點遊戲,因而就琢磨着是否是開發一個安卓手機版本。而後上網上一搜,發現已經被別人給開發爛了啊。不過這隻能說明這個小遊戲要想賺廣告費很難了,可是拿來鍛鍊和在妹紙面前裝逼仍是頗有價值的,嘿嘿,想到這裏,我最終仍是花了3天時間開發了一個小遊戲出來。java

 

  算法實現

  在網上試玩了一個flash的版本,發現還須要實現計算全部正確的結果,而後網上稍微百度了下思路,就開始本身實現了。我開始時大概的思路就是窮舉出全部的數字和算式的排列組合,而後一一進行驗算,中間碰到兩個問題,android

  1. 第一是計算順序的問題,稍微思考一下,就會發現,+,*是不考慮前後順序的,-,/是考慮前後順序的,因此考慮計算順序後每兩個數都會有6種計算方法。而括號也會產生不少不一樣的狀況。
  2. 第二是保存計算的表達式的問題,由於窮舉完了,計算機是知道答案了,可是用戶仍是不知道啊,因此得想辦法保存起來(這個問題開始時沒注意,後來小花了點時間才完美解決的,後面會有說明)。

 

  而後,具體怎樣進行遍歷才能作到既不重複又無遺漏呢? 個人思路是這樣的,仍是得利用遞歸來簡化實現,雖然遞歸很耗資源,可是做爲非acm大神,算法水平通常般的我來講,仍是先從簡單的角度考慮。一個算式,無論包不包括括號,均可以抽象成兩個數的計算的疊加,由於每次單個運算都是拿兩個數運算的。而後再經過遞歸,將計算的結果和其餘的數從新作兩個數的運算,一直遞歸到只剩下一個結果時,那麼這個數就是這種計算方法獲得的答案了,和24比較就能夠了。web

 

  至於每個運算軌跡獲得的表達式該怎麼保存呢?個人作法是用一個類封裝起來,而後維護兩個數組,一個是數字(這個數字既是用戶輸入的,也能夠是兩個或多個數運算獲得的結果),另外一個就是這個數對應的表達式(當這個數是用戶輸入的時候就是一個數字而已,當這個數字是運算的結果時就是算式)的字符串。算法

 

  實現代碼:數組

  1 package net.yunstudio.p24.util;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashSet;
  5 import java.util.List;
  6 import java.util.Random;
  7 import java.util.Set;
  8 
  9 import com.umeng.a.a.a.b.n;
 10 
 11 public class Count24 {
 12     private List<String> answerList=new ArrayList<String>();
 13     public List<String> getAnswerList() {
 14         return answerList;
 15     }
 16     public static class Data{
 17         public float[]  arr;
 18         public String expStr="";
 19         public String[] strs;
 20         public Data(){}
 21         public Data(int a,int b,int c,int d) {
 22             arr=new float[]{a,b,c,d};
 23             strs=new String[]{a+"",b+"",c+"",d+""};
 24             expStr=a+"";
 25         }
 26         public Data(int arr[]) {
 27             this.arr=new float[]{arr[0],arr[1],arr[2],arr[3]};
 28             this.strs=new String[]{arr[0]+"",arr[1]+"",arr[2]+"",arr[3]+""};
 29         }
 30     }
 31     public void count(Data data){
 32         float[] arr=data.arr;
 33         if(arr.length<=1){
 34             if(arr.length==1&&arr[0]==24){
 35                 answerList.add(data.expStr.substring(1, data.expStr.length()-1));
 36             }
 37             return ;
 38         }
 39         for(int i=0,len=arr.length;i<len-1; i++){
 40             for(int j=i+1;j<len;j++){
 41                 float x=arr[i];
 42                 float y=arr[j];
 43                 String xs=data.strs[i];
 44                 String ys=data.strs[j];
 45                 for(int k=0;k<6;k++){
 46                     Data newData=getNewArr(data,i);
 47                     switch(k){
 48                         case 0:
 49                         newData.arr[j-1]=x+y;
 50                             newData.expStr=xs+"+"+ys;
 51                         break;
 52                         case 1:
 53                         newData.arr[j-1]=x-y;
 54                             newData.expStr=xs+"-"+ys;
 55                         break;
 56                         case 2:
 57                         newData.arr[j-1]=y-x;
 58                         newData.expStr=ys+"-"+xs;
 59                         break;
 60                         case 3:
 61                         newData.arr[j-1]=x*y;
 62                             newData.expStr=xs+"*"+ys;
 63                         break;
 64                         case 4:
 65                         if(y!=0){
 66                             newData.arr[j-1]=x/y;
 67                                 newData.expStr=xs+"/"+ys;
 68                         }else {
 69                             continue;
 70                         }
 71                         break;
 72                         case 5:
 73                         if(x!=0){
 74                             newData.arr[j-1]=y/x;
 75                                 newData.expStr=ys+"/"+xs;
 76                         }else {
 77                             continue;
 78                         }
 79                         break;
 80                     }
 81                     newData.expStr="("+newData.expStr+")";
 82                     newData.strs[j-1]=newData.expStr;
 83                     count(newData);
 84                 }
 85             }
 86         }
 87         
 88     }
 89     private static Data getNewArr(Data data, int i) {
 90         Data newData=new Data();
 91         newData.expStr=data.expStr;
 92         newData.arr=new float[data.arr.length-1];
 93         newData.strs=new String[data.arr.length-1];
 94         for(int m=0,len=data.arr.length,n=0;m<len;m++){
 95             if(m!=i){
 96                 newData.arr[n]=data.arr[m];
 97                 newData.strs[n]=data.strs[m];
 98                 n++;
 99             }
100         }
101         return newData;
102     }
103     
104     public static final List<String> easyCount(int[] curRandNums){
105         Count24 count24=new Count24();
106         count24.count(new Data(curRandNums));
107         Set<String> set=new HashSet<String>(count24.getAnswerList());//去重
108         return new ArrayList<String>(set);
109     }
110     
111     public static void main(String[] args) throws InterruptedException {
112         long start=System.currentTimeMillis();
113         List<String> answerStris=easyCount(new int[]{1,2,3,4});
114         System.out.println(System.currentTimeMillis()-start);
115 
116         for (String string : answerStris) {
117             System.out.println(string);
118         }
119     }
120 }
24點算法實現

  

 

  在電腦上面(神舟i7)大概須要60ms,這個速度初看仍是能夠接受的,可是到了手機上,竟然須要6秒以上!!不過無心中發現,在android系統中對大量運算有優化,貌似計算了必定次數以後系統會緩存編譯後的本地代碼,而後手機上也能夠像電腦上同樣秒算了。緩存

 

   以後又花了一天作了個醜陋無比的簡單界面,再花了一天時間加上積分功能,修復各類bug,添加廣告和統計sdk,上傳應用市場。。dom

 

完整應用體驗:http://as.baidu.com/a/item?docid=6481764&pre=web_am_seide

相關文章
相關標籤/搜索