java 24点算法实现
最近闲来无事,突然怀念起小时候和堂兄表姐们经常玩24点游戏,于是就琢磨着是不是开发一个安卓手机版本。然后上网上一搜,发现已经被别人给开发烂了啊。不过这只能说明这个小游戏要想赚广告费很难了,但是拿来锻炼和在妹纸面前装逼还是很有价值的,嘿嘿,想到这里,我最终还是花了3天时间开发了一个小游戏出来。
算法实现
在网上试玩了一个flash的版本,发现还需要实现计算所有正确的结果,然后网上稍微百度了下思路,就开始自己实现了。我开始时大概的思路就是穷举出所有的数字和算式的排列组合,然后一一进行验算,中间碰到两个问题,
- 第一是计算顺序的问题,稍微思考一下,就会发现,+,*是不考虑先后顺序的,-,/是考虑先后顺序的,所以考虑计算顺序后每两个数都会有6种计算方法。而括号也会产生很多不同的情况。
- 第二是保存计算的表达式的问题,因为穷举完了,计算机是知道答案了,但是用户还是不知道啊,所以得想办法保存起来(这个问题开始时没注意,后来小花了点时间才完美解决的,后面会有说明)。
然后,具体怎样进行遍历才能做到既不重复又无遗漏呢? 我的思路是这样的,还是得利用递归来简化实现,虽然递归很耗资源,但是作为非acm大神,算法水平一般般的我来说,还是先从简单的角度考虑。一个算式,不管包不包括括号,都可以抽象成两个数的计算的叠加,因为每次单个运算都是拿两个数运算的。然后再通过递归,将计算的结果和其他的数重新做两个数的运算,一直递归到只剩下一个结果时,那么这个数就是这种计算方法得到的答案了,和24比较就可以了。
至于每一个运算轨迹得到的表达式该怎么保存呢?我的做法是用一个类封装起来,然后维护两个数组,一个是数字(这个数字既是用户输入的,也可以是两个或多个数运算得到的结果),另一个就是这个数对应的表达式(当这个数是用户输入的时候就是一个数字而已,当这个数字是运算的结果时就是算式)的字符串。
实现代码:
package net.yunstudio.p24.util; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set; import com.umeng.a.a.a.b.n; public class Count24 {
private List<String> answerList=new ArrayList<String>();
public List<String> getAnswerList() {
return answerList;
}
public static class Data{
public float[] arr;
public String expStr="";
public String[] strs;
public Data(){}
public Data(int a,int b,int c,int d) {
arr=new float[]{a,b,c,d};
strs=new String[]{a+"",b+"",c+"",d+""};
expStr=a+"";
}
public Data(int arr[]) {
this.arr=new float[]{arr[0],arr[1],arr[2],arr[3]};
this.strs=new String[]{arr[0]+"",arr[1]+"",arr[2]+"",arr[3]+""};
}
}
public void count(Data data){
float[] arr=data.arr;
if(arr.length<=1){
if(arr.length==1&&arr[0]==24){
answerList.add(data.expStr.substring(1, data.expStr.length()-1));
}
return ;
}
for(int i=0,len=arr.length;i<len-1; i++){
for(int j=i+1;j<len;j++){
float x=arr[i];
float y=arr[j];
String xs=data.strs[i];
String ys=data.strs[j];
for(int k=0;k<6;k++){
Data newData=getNewArr(data,i);
switch(k){
case 0:
newData.arr[j-1]=x+y;
newData.expStr=xs+"+"+ys;
break;
case 1:
newData.arr[j-1]=x-y;
newData.expStr=xs+"-"+ys;
break;
case 2:
newData.arr[j-1]=y-x;
newData.expStr=ys+"-"+xs;
break;
case 3:
newData.arr[j-1]=x*y;
newData.expStr=xs+"*"+ys;
break;
case 4:
if(y!=0){
newData.arr[j-1]=x/y;
newData.expStr=xs+"/"+ys;
}else {
continue;
}
break;
case 5:
if(x!=0){
newData.arr[j-1]=y/x;
newData.expStr=ys+"/"+xs;
}else {
continue;
}
break;
}
newData.expStr="("+newData.expStr+")";
newData.strs[j-1]=newData.expStr;
count(newData);
}
}
} }
private static Data getNewArr(Data data, int i) {
Data newData=new Data();
newData.expStr=data.expStr;
newData.arr=new float[data.arr.length-1];
newData.strs=new String[data.arr.length-1];
for(int m=0,len=data.arr.length,n=0;m<len;m++){
if(m!=i){
newData.arr[n]=data.arr[m];
newData.strs[n]=data.strs[m];
n++;
}
}
return newData;
} public static final List<String> easyCount(int[] curRandNums){
Count24 count24=new Count24();
count24.count(new Data(curRandNums));
Set<String> set=new HashSet<String>(count24.getAnswerList());//去重
return new ArrayList<String>(set);
} public static void main(String[] args) throws InterruptedException {
long start=System.currentTimeMillis();
List<String> answerStris=easyCount(new int[]{1,2,3,4});
System.out.println(System.currentTimeMillis()-start); for (String string : answerStris) {
System.out.println(string);
}
}
}
24点算法实现
在电脑上面(神舟i7)大概需要60ms,这个速度初看还是可以接受的,但是到了手机上,居然需要6秒以上!!不过无意中发现,在android系统中对大量运算有优化,貌似计算了一定次数之后系统会缓存编译后的本地代码,然后手机上也可以像电脑上一样秒算了。
之后又花了一天做了个丑陋无比的简单界面,再花了一天时间加上积分功能,修复各种bug,添加广告和统计sdk,上传应用市场。。
完整应用体验:http://as.baidu.com/a/item?docid=6481764&pre=web_am_se
java 24点算法实现的更多相关文章
- Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...
- Java 常用排序算法/程序员必须掌握的 8大排序算法
Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...
- Java数据结构和算法 - 递归
三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,……中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...
- Java数据结构和算法 - 数组
Q: 数组的创建? A: Java中有两种数据类型,基本类型和对象类型,在许多编程语言中(甚至面向对象语言C++),数组也是基本类型.但在Java中把数组当做对象来看.因此在创建数组时,必须使用new ...
- Java各种排序算法
Java各种排序算法详解 排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有 ...
- java加解密算法
什么是加密算法?百度百科给出的解释如下: 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容, ...
- 【趣味分享】C#实现回味童年的24点算法游戏
一.24点游戏玩法规则效果展示 1.初始化界面 2.开始游戏界面 3.游戏超时界面 4.查看答案界面 5.答对界面 6.答错界面 7.计算表达式的验证界面 8.一副牌算完开始新一副牌界面 到这里24点 ...
- Java字符串排列算法
Java字符串排列算法 题目:现有ABCDE 5个球 构成的排列组合 可重复抽取 最多取到16个 共有多少种组合方式? 比如:取1个球可以构成的组合有 A B C D E 共5种,取2个球可以构成的组 ...
- Java实现KMP算法
/** * Java实现KMP算法 * * 思想:每当一趟匹配过程中出现字符比较不等,不需要回溯i指针, * 而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远 * 的一段 ...
随机推荐
- 苹果App转移图文详解-Transfer App
此文章只是为了记录一个Apple ID下的APP,转移到另外一个Apple ID 账户下.为了说的清楚下面用A账户(有App,要转出去)B账户(接收A账户App,接收者),来说明. 1. 登 ...
- centos -bash-4.1$ 不显示用户名路径
1.在Terminal输入: vi ~/.bash_profile 2.如果没有.bash_profile可以自己添加.然后往文件中添加如下内容: export PS1=’[\u@\h \W]$ 注意 ...
- 史上最全Vim快捷键键位图(入门到进阶)
经典版 下面这个键位图应该是大家最常看见的经典版了. 对应的简体中文版 其实经典版是一系列的入门教程键位图的组合结果,下面是不同编辑模式下的键位图. 入门版 基本操作的入门版. 进阶版 增强版 下图是 ...
- kvm介绍
KVM(Kernel-Based Virtual Machines)是一个基于Linux内核的虚拟化技术, 可以直接将Linux内核转换为Hypervisor(系统管理程 序)从而使得Linux内核能 ...
- C++实现按绩点排名
题目内容:有一些班级的学生需要按绩点计算并排名.每门课的成绩只有在60分以上(含),才予以计算绩点.课程绩点的计算公式为:(课程成绩-50)÷10×学分数.一个学生的总绩点为其所有课程绩点总和除以10 ...
- Windows上搭建android开发环境
在搭建android开发环境时需要四部分内容,框架如下 其中Java SDK和Eclipse在java4android中有过介绍,重点介绍ADT和Android SDK的安装. 安装Android S ...
- C++ STL vector 内存分配
vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储. 当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间.拷贝元素.撤销 ...
- 软件工程个人作业4(课堂练习&&课堂作业)
题目:返回一个整数数组中最大子数组的和. 要求:1.输入一个整型数组,数组里有正书和负数. 2.数组中连续的一个或者多个整数组,每个子数组都有一个和. 3.求所有子数组的和的最大值.要求时间复杂度为0 ...
- hdu 2647 Reward
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2647 Reward Description Dandelion's uncle is a boss o ...
- hdu 1973 Prime Path
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1973 Prime Path Description The ministers of the cabi ...