题目描述
设计算法,在 1~9 共九个数字之间任意添加四则运算( + - × ÷ )符号,使表达式的值为 100 。寻找成立的表达式并输出。
例:1+2×3÷4+5+6-7×8-9=100(此等式仅表述输出样式,自身不成立!)
注意:不可改变数字顺序,不需要将多个数值合并,每两个数字之间都要存在四则运算符。
提示:使用递归算法。
算法源码(Java)
import static java.lang.Math.abs;
/**
* @author Dragon1573
*/
public class Main {
public static void main(String[] args) {
traverse(0, 1, 1, "1");
}
/**
* @param result
* 前序表达式计算结果
* @param i
* 当前位数字
* @param last
* 最近乘除法子表达式计算结果
* @param expression
* 表达式字符串
*/
private static void traverse(float result, float i, float last, String expression) {
// 停止条件
if (i == 9) {
if (abs(result + last - 100) < 0.001) {
System.out.println(expression + "=100");
}
return;
}
// 加法
traverse(result + last, i + 1, i + 1, expression + "+" + (int)(i + 1));
// 减法
traverse(result + last, i + 1, -i - 1, expression + "-" + (int)(i + 1));
// 乘法
traverse(result, i + 1, last * (i + 1), expression + "*" + (int)(i + 1));
// 除法
traverse(result, i + 1, last / (i + 1), expression + "/" + (int)(i + 1));
}
}
将乘法和除法等需要优先计算的子表达式记为『顶级表达式』,将加法和减法等后续计算的子表达式记为『次级表达式』。算法的主要思想是借助两个参数,分别存储不包含最近顶级表达式的完全前序子表达式值和最近顶级表达式值。以表达式 1+2×3÷4+5+6-7×8 为例,两个参数分别对应子表达式 1+2×3÷4+5+6 和 7×8 的值。
这种递归方法将顶级表达式的结果计算完毕后再整体合并到前序子表达式中,巧妙地解决了运算符优先级问题。
求解结果
1+2+3+4+5+6+7+8*9=100
1+2+3-4*5+6*7+8*9=100
1+2-3*4+5*6+7+8*9=100
1+2-3*4-5+6*7+8*9=100
1+2*3+4*5-6+7+8*9=100
1+2*3*4*5/6+7+8*9=100
1-2+3*4*5+6*7+8-9=100
1-2+3*4*5-6+7*8-9=100
1-2*3+4*5+6+7+8*9=100
1-2*3-4+5*6+7+8*9=100
1-2*3-4-5+6*7+8*9=100
1*2*3+4+5+6+7+8*9=100
1*2*3-4*5+6*7+8*9=100
1*2*3*4+5+6+7*8+9=100
1*2*3*4+5+6-7+8*9=100
Process finished with exit code 0