问题:
给出a, b, c, d四个数且1<=a, b, c, d<=10;
对这四个数使用加减乘除运算,判断这四个数的能否等于24;
能的话输出表达式(可能有多个表达式)
例如
输入
2 2 2 3
输出
222*3(或其他表达式)
代码如下:
public class Main{
public static String random_p() {
int a = (int)(Math.random()*4);
if (a==1) return "+";
if (a==2) return "-";
if (a==3) return "*";
return "/";
}
public static void shuffle(String[] data) {
for(int i=0; i<data.length; i++) {
int j = (int)(Math.random()*data.length);
String temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
public static int op(int a, int b, String oper) throws Exception {
if (oper.equals("+")) return a+b;
if (oper.equals("-")) return a-b;
if (oper.equals("*")) return a*b;
if(a%b != 0) throw new Exception("not /");
return a / b;
}
public static boolean jisuan(String[] data) {
Stack stk = new Stack();
try {
for(int i=0; i<data.length; i++) {
if(data[i].equals("+") || data[i].equals("-")
||data[i].equals("*") || data[i].equals("/")) {
int a = Integer.parseInt((String) stk.pop());
int b = Integer.parseInt((String) stk.pop());
try {
stk.push(op(a, b, data[i]) + "");
} catch (Exception e) {
// TODO Auto-generated catch block
return false;
}
}
else {
stk.push(data[i]);
}
}
}
catch (Exception e) {return false;}
if (stk.size()==1 && stk.pop().equals("24")) return true;
return false;
}
public static void show(String[] data) {
Stack stk = new Stack();
for(int i=0; i<data.length; i++) {
if(data[i].equals("+") || data[i].equals("-")
||data[i].equals("*") || data[i].equals("/")) {
stk.push("(" + stk.pop() + data[i] + stk.pop() + ")");
}
else {
stk.push(data[i]);
}
}
System.out.println(stk.pop());
}
public static void f(String[] ss) {
for (int k=0; k<1000*100; k++) {
String[] buf = new String[7];
for(int i=0; i<4; i++) buf[i] = ss[i];
for(int i=4; i<7; i++) buf[i] = random_p();
shuffle(buf);
if(jisuan(buf)) {
show(buf);
break;
}
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String[] ss = null;
while(true) {
System.out.println("请输入四个整数:");
ss = scan.nextLine().split(" +");
f(ss);
}
}
}
这道题的思路是先创建一个buf数组,长度为7,前四个元素是随机输入的四个数字,
后三个利用随机数从“+”,“-”,“*”,“/“ 四个符号中选择三个,然后将他们进行组合,
因此这是通过多次模拟去寻找正确答案。这个方法次数越多越管用。
shuffle函数把buf数组中的元素随机的两两交换,打乱里面的顺序。jisuan函数来判断
四个数字的组合能否满足等于24的要求。这里使用了中缀表达式的知识。通过栈每次
弹出两个数字,运算得到结果后再压入栈中。为了将整个表达式可视化出来,又写了
一个show方法。每次压入栈中的不是计算结果,而是计算公式。
要注意的是异常的使用,jisuan函数中当栈为空时再pop会报异常,因此需要处理。