最近閒來無事,忽然懷念起小時候和堂兄表姐們常常玩24點遊戲,因而就琢磨着是否是開發一個安卓手機版本。而後上網上一搜,發現已經被別人給開發爛了啊。不過這隻能說明這個小遊戲要想賺廣告費很難了,可是拿來鍛鍊和在妹紙面前裝逼仍是頗有價值的,嘿嘿,想到這裏,我最終仍是花了3天時間開發了一個小遊戲出來。java
在網上試玩了一個flash的版本,發現還須要實現計算全部正確的結果,而後網上稍微百度了下思路,就開始本身實現了。我開始時大概的思路就是窮舉出全部的數字和算式的排列組合,而後一一進行驗算,中間碰到兩個問題,android
而後,具體怎樣進行遍歷才能作到既不重複又無遺漏呢? 個人思路是這樣的,仍是得利用遞歸來簡化實現,雖然遞歸很耗資源,可是做爲非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 }
在電腦上面(神舟i7)大概須要60ms,這個速度初看仍是能夠接受的,可是到了手機上,竟然須要6秒以上!!不過無心中發現,在android系統中對大量運算有優化,貌似計算了必定次數以後系統會緩存編譯後的本地代碼,而後手機上也能夠像電腦上同樣秒算了。緩存
以後又花了一天作了個醜陋無比的簡單界面,再花了一天時間加上積分功能,修復各類bug,添加廣告和統計sdk,上傳應用市場。。dom
完整應用體驗:http://as.baidu.com/a/item?docid=6481764&pre=web_am_seide