如何修正Exercise20_23.java的表达式求值代码以匹配预期结果?
常见问题分析与修正方案
在给表达式求值功能添加^(幂运算)和%(取余)时,最容易踩的坑集中在运算符优先级、结合性以及栈处理逻辑上,以下是具体问题点和修正代码:
核心错误点
- 幂运算优先级错误:未将
^的优先级设为高于乘除(*//),导致计算顺序混乱。 - 幂运算结合性错误:
^是右结合(如2^3^2 = 2^(3^2) = 512),若按左结合处理会得到(2^3)^2=64,与预期不符。 - 取余运算逻辑错误:操作数顺序搞反(应是
a%b而非b%a),或未处理负数/浮点数的取余规则。 - 栈弹出条件错误:未区分左/右结合运算符的弹出逻辑,导致栈中运算符的弹出时机错误。
修正代码示例
1. 运算符优先级与结合性判断
// 返回运算符优先级:^ > *、/、% > +、- private static int getPriority(char op) { return switch(op) { case '+', '-' -> 1; case '*', '/', '%' -> 2; case '^' -> 3; default -> 0; }; } // 判断是否为左结合运算符:仅^是右结合 private static boolean isLeftAssociative(char op) { return op != '^'; }
2. 运算符栈的弹出逻辑修正
在处理运算符入栈时,针对右结合的^调整弹出条件:
while (!opStack.isEmpty()) { char topOp = opStack.peek(); // 左结合:栈顶优先级 >= 当前则弹出;右结合:栈顶优先级 > 当前才弹出 boolean shouldPop = isLeftAssociative(op) ? getPriority(topOp) >= getPriority(op) : getPriority(topOp) > getPriority(op); if (!shouldPop) break; // 弹出栈顶运算符并计算 calculate(opStack, numStack); } opStack.push(op);
3. 运算逻辑实现(含^和%)
private static void calculate(Stack<Character> opStack, Stack<Double> numStack) { char op = opStack.pop(); double b = numStack.pop(); double a = numStack.pop(); double result = 0; switch(op) { case '+' -> result = a + b; case '-' -> result = a - b; case '*' -> result = a * b; case '/' -> result = a / b; case '%' -> result = a % b; // 注意操作数顺序:a对b取余 case '^' -> result = Math.pow(a, b); // 幂运算:a的b次方 } numStack.push(result); }
验证测试用例
针对预期输出的典型场景验证:
3^2→ 9(幂运算优先级正确)10%3→ 1(取余操作数顺序正确)2^3^2→ 512(右结合逻辑生效)10+3*2^2→ 22(优先级顺序:^ > * > +)
内容的提问来源于stack exchange,提问作者RWorker
相关产品推荐
相关产品推荐

