C#多表达式计算器问题求助:仅支持加法,无法处理减乘除
问题排查与修正
你的计算器代码存在以下核心问题,导致无法正确处理减、乘、除,甚至连多位数都无法正确解析:
- 多位数解析错误:当前代码把连续数字直接相加(比如"58"会被解析成5+8=13),正确逻辑应该是将当前值乘以10再加上新数字。
- 操作符处理逻辑倒置:遇到操作符时,应该先把当前输入的数字压入栈,再处理运算符的计算逻辑,而非直接调用计算方法。
- PerformCalculation方法逻辑混乱:该方法错误地在内部重复压栈,且未正确利用当前输入的数字,导致计算逻辑完全错位。
- 缺少表达式末尾的最终计算:遍历完所有字符后,最后一个数字还未参与计算,需要完成收尾处理。
修正后的完整代码
namespace Calculator { class Program { static void Main(string[] args) { var expression = "4+5*8-3/2"; var calculator = new Calculator(); foreach (var chr in expression) { calculator.KeyPress(chr); } // 处理表达式末尾的最终计算 calculator.FinishCalculation(); Console.WriteLine(calculator.Value); } } public class Calculator { public double? Value { get; private set; } private Stack<double> stack = new Stack<double>(); private char? pendingOperator = null; // 存储待执行的运算符 public void KeyPress(char key) { if (char.IsDigit(key)) { // 正确解析多位数 if (Value == null) { Value = char.GetNumericValue(key); } else { Value = Value * 10 + char.GetNumericValue(key); } } else if (key == '+' || key == '-' || key == '*' || key == '/') { // 先处理上一个待执行的运算符 if (pendingOperator.HasValue && Value.HasValue) { double currentValue = Value.Value; double left = stack.Pop(); double result = Calculate(left, currentValue, pendingOperator.Value); stack.Push(result); Value = null; } else if (Value.HasValue) { // 第一次遇到运算符,直接把当前数字压栈 stack.Push(Value.Value); Value = null; } // 记录当前运算符为待执行 pendingOperator = key; } } // 完成表达式末尾的最终计算 public void FinishCalculation() { if (pendingOperator.HasValue && Value.HasValue) { double currentValue = Value.Value; double left = stack.Pop(); Value = Calculate(left, currentValue, pendingOperator.Value); pendingOperator = null; } } // 基础计算逻辑 private double Calculate(double left, double right, char op) { return op switch { '+' => left + right, '-' => left - right, '*' => left * right, '/' => right != 0 ? left / right : throw new DivideByZeroException("除数不能为0"), _ => left }; } } }
关键修改说明
- 多位数解析修复:将
Value = Value + Char.GetNumericValue(key)改为Value = Value * 10 + char.GetNumericValue(key),确保连续数字被解析为正确数值。 - 新增pendingOperator变量:用于存储待执行的运算符,解决运算顺序错位问题。
- 重构操作符处理逻辑:遇到新运算符时,先执行上一个运算符的计算,再将当前数字压栈,记录新运算符。
- 新增FinishCalculation方法:遍历完所有字符后,执行最后一个运算符的计算,得到最终结果。
- 拆分Calculate方法:将运算逻辑独立出来,代码更清晰,同时增加了除零异常判断。
注意:当前代码已支持基础加减乘除,但尚未处理运算符优先级(如先乘除后加减)。若需支持优先级,需进一步优化为双栈逻辑(一个存数字、一个存运算符,根据优先级判断是否提前计算)。
内容的提问来源于stack exchange,提问作者CarlE
相关产品推荐
相关产品推荐

