题目要求:
用户输入4位个位数(1~9),四个数之间只能通过+,-,*,/运算进行连接
请输出四则运算表达式,其求值结果为24。然后输出所有求值结果为24的组合。
你能不能不通过四重循环来产生这4个参与运算的数。
代码如下:
package ergodic;
import java.util.*;
/**
* @ Author :heywecome
* @ Date :Created in 20:32 2018/12/20
* @ Description:${description}
* @ Modified By:
* @Version: $version$
*/
public class TwentyFour {
// 用户输入4位个位数(1~9),四个数之间只能通过+,-,*,/运算进行连接,请输出四则运算表达式,
// 其求值结果为24。然后输出所有求值结果为24的组合。你能不能不通过四重循环来产生这4个参与运算的数。
static final String PLUS = "+";
static final String DIVIDE = "-";
static final String MULTIPLY= "*";
static final String SUBSTRACT = "/";
static ArrayList resultList = new ArrayList();
static ArrayList operatorList = new ArrayList();
static String[] operator = {PLUS,DIVIDE,MULTIPLY,SUBSTRACT}; // 操作符的排列
public static void findAllSolution(int[] nums){
perm(nums,0,nums.length-1); // 产生数的排列
perm(operator,0,operator.length-1);
for(int i = 0; i < nums.length; i++){ // 四个数产生不同的排列
for(int j = 0; j < operatorList.size(); j++){
String formula = new String();
int[] numsTemp = (int[]) resultList.get(i);
String[] operatorTemp = (String[])operatorList.get(j);
// 加括号的第一种情况: (a+b)+(c+d)
formula += "("+numsTemp[0]+ operatorTemp[0]+numsTemp[1]+")"+ operatorTemp[1]
+"("+numsTemp[2]+operatorTemp[2]+numsTemp[3]+")";
if(evaluateExpression(formula) == 24){
System.out.println(formula);
}
formula = "";
// 加括号的第二种情况: ((a+b)+c)+d,
formula += "(("+numsTemp[0]+ operatorTemp[0]+numsTemp[1]+")"+ operatorTemp[1]+numsTemp[2]
+")"+operatorTemp[2]+numsTemp[3];
if(evaluateExpression(formula) == 24){
System.out.println(formula);
}
formula = "";
// 加括号的第三种情况: (a+(b+c))+d
formula += "("+numsTemp[0]+operatorTemp[0]+ "(" +numsTemp[1]+operatorTemp[1]
+numsTemp[2]+"))"+operatorTemp[2]+numsTemp[3];
if(evaluateExpression(formula) == 24){
System.out.println(formula);
}
}
}
}
/** 计算表达式 */
public static int evaluateExpression(String expression) {
// 创建操作数的stack
GenericStack<Integer> operandStack = new GenericStack<Integer>();
// 创建操作符的stack
GenericStack<Character> operatorStack = new GenericStack<Character>();
// 真正的操作数和操作符
// 去掉首尾空格
java.util.StringTokenizer tokens = new java.util.StringTokenizer(
expression, "()+-/*", true);
// 步骤1:搜索token
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim(); // 压缩一个token
if (token.length() == 0) // 为空时
continue; // 返回到循环压缩下一个字符
else if (token.charAt(0) == '+' || token.charAt(0) == '-') {
// Process all +, -, *, / in the top of the operator stack
// 把所有的 +,-,*,/ 都放在operator栈中
while (!operatorStack.isEmpty()
&& (operatorStack.peek() == '+' || operatorStack.peek() == '-'
|| operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
processAnOperator(operandStack, operatorStack);
}
// 把 + 或者 - 放进operator stack中
operatorStack.push(token.charAt(0));
} else if (token.charAt(0) == '*' || token.charAt(0) == '/') {
while (!operatorStack.isEmpty()
&& (operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
processAnOperator(operandStack, operatorStack);
}
operatorStack.push(token.charAt(0));
} else if (token.trim().charAt(0) == '(') {
operatorStack.push('(');
} else if (token.trim().charAt(0) == ')') {
while (operatorStack.peek() != '(') {
processAnOperator(operandStack, operatorStack);
}
operatorStack.pop();
} else {
operandStack.push(new Integer(token));
}
}
while (!operatorStack.isEmpty()) {
processAnOperator(operandStack, operatorStack);
}
// 返回结果
return operandStack.pop();
}
public static void processAnOperator(GenericStack<Integer> operandStack,
GenericStack<Character> operatorStack) {
char op = operatorStack.pop();
int op1 = operandStack.pop();
int op2 = operandStack.pop();
if (op == '+')
operandStack.push(op2 + op1);
else if (op == '-')
operandStack.push(op2 - op1);
else if (op == '*')
operandStack.push(op2 * op1);
else if (op == '/'){
operandStack.push(0);
}
}
/**
* 产生数的排列
* @param v
* @param left
* @param right
*/
public static void perm(int[] v, int left, int right) {
if (left == right) {
int[] temp = new int[v.length];
for (int i = 0; i < v.length; i++) {
temp[i] = v[i];
}
resultList.add(temp);
} else {
for (int i = left; i <= right; i++) {
swap(v, left, i);
perm(v, left + 1, right);
swap(v, left, i);
}
}
}
/**
* 产生操作符的排列
* @param v
* @param left
* @param right
*/
public static void perm(String[] v, int left, int right) {
if (left == right) {
String[] temp = new String[v.length];
for (int i = 0; i < v.length; i++) {
temp[i] = v[i];
}
operatorList.add(temp);
} else {
for (int i = left; i <= right; i++) {
swap(v, left, i);
perm(v, left + 1, right);
swap(v, left, i);
}
}
}
private static void swap(int[] v, int left, int i) {
int temp = v[left];
v[left] = v[i];
v[i] = temp;
}
private static void swap(String[] v, int left, int i) {
String temp = v[left];
v[left] = v[i];
v[i] = temp;
}
public static void main(String[] args){
int a = (int)(Math.random()*9+1);
int b = (int)(Math.random()*9+1);
int c = (int)(Math.random()*9+1);
int d = (int)(Math.random()*9+1);
int[] nums = {a,b,c,d};
// int[] nums = {7,3,9,7};
// int[] nums = {3,4,8,3};
System.out.println("生成的四个数字为:"+a+" "+b+" "+c+" "+d);
System.out.println("所有的表达式为:");
findAllSolution(nums);
}
}
测试数据如下:
采用的是随机生成的四个数字,并求出能否得到24点。