表达式求值
1、栈实现中缀表达式求值
package bytedance;
import java.util.*;
public class Expression {
public static void main(String[] args) {
System.out.println(solve("2*(3+5)-7"));
System.out.println(solve("(2+3)*4-5"));
}
static int[][] priorities = {
//+ - * / ( )
{1, 1, -1, -1, -1, 1}, // +
{1, 1, -1, -1, -1, 1}, // -
{1, 1, 1, 1, -1, 1}, // *
{1, 1, 1, 1, -1, 1}, // /
{-1, -1, -1, -1, -1, 0}, // (
{1, 1, 1, 1, 0, 1} // )
};
static Map<Character, Integer> map = new HashMap<>();
public static int solve(String expression) {
char[] cs = expression.toCharArray();
char[] ss = {'+', '-', '*', '/', '(', ')'};
for (int i = 0; i < ss.length; i++) map.put(ss[i], i);
Deque<Character> ops = new ArrayDeque<>();
Deque<Integer> nums = new ArrayDeque<>();
for (int i = 0; i < cs.length; i++) {
if (Character.isDigit(cs[i])) { // 如果是操作数,直接入栈
nums.push(cs[i] - '0');
} else { // 如果是运算符
if (ops.isEmpty()) ops.push(cs[i]);
else {
char op1 = ops.peek(), op2 = cs[i];
int comp = priorities[map.get(op1)][map.get(op2)];
if (comp > 0) { // 栈顶优先级更大
op1 = ops.pop(); // 操作符退栈
int num2 = nums.pop(), num1 = nums.poll();
nums.push(calculate(num1, num2, op1)); // 运算
i--; // 注意一定要将i--因为大于不扫描下一个字符
} else if (comp == 0) {
ops.pop(); // 弹出 ( 运算符
} else {
ops.push(op2);
}
}
}
}
while (!ops.isEmpty()) {
int num2 = nums.poll(), num1 = nums.poll();
nums.push(calculate(num1, num2, ops.pop()));
}
return nums.peek();
}
private static int calculate(int num1, int num2, char op) {
if (op == '+') return num1 + num2;
else if (op == '-') return num1 - num2;
else if (op == '*') return num1 * num2;
return num1 / num2;
}
}
2、递归实现表达式求值
package bytedance;
public class ExpressionRecursion {
static int idx = 0;
static char[] cs;
public static void main(String[] args) {
cs = "(7+2)/3-5*2+12*(4+3)".toCharArray();
System.out.println(expressionValue());
}
// 求一个因子的值(一个因子可以是一个数,或者一个(xxx)表达式)
public static int factorValue() {
int ret = 0;
char c = cs[idx];
if (c == '(') { // 因子是由左右括号和表达式组成
idx++; // 把左括号扔掉
ret = expressionValue(); // 处理表达式
idx++; // 把右括号扔掉
} else { // 因子是一个数
while (idx < cs.length && Character.isDigit(cs[idx])) {
ret = ret * 10 + (cs[idx++] - '0');
}
}
return ret;
}
// 求一项的值(一个项必须是+-号的一边,由至少一个因子组成)
public static int termValue() {
// 求一个项的值
int ret = factorValue();
while (idx < cs.length) {
char op = cs[idx];
if (op == '*' || op == '/') { // 说明后面还有后续因子
idx++;
int val = factorValue();
if (op == '*') ret *= val;
else ret /= val;
} else break; // 没有因子了
}
return ret;
}
// 表达式(由多个项组成,通过+-号运算这些项)
public static int expressionValue() { // 求一个表达式的值
int ret = termValue(); // 求第一项的值
while (idx < cs.length) {
char op = cs[idx];
if (op == '+' || op == '-') {
idx++;
int val = termValue();
if (op == '+') ret += val;
else ret -= val;
} else break; // 如果是右括号,说明输入结束
}
return ret;
}
}
查看7道真题和解析