You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
            };
        }
    }
}

关键修改说明

  1. 多位数解析修复:将Value = Value + Char.GetNumericValue(key)改为Value = Value * 10 + char.GetNumericValue(key),确保连续数字被解析为正确数值。
  2. 新增pendingOperator变量:用于存储待执行的运算符,解决运算顺序错位问题。
  3. 重构操作符处理逻辑:遇到新运算符时,先执行上一个运算符的计算,再将当前数字压栈,记录新运算符。
  4. 新增FinishCalculation方法:遍历完所有字符后,执行最后一个运算符的计算,得到最终结果。
  5. 拆分Calculate方法:将运算逻辑独立出来,代码更清晰,同时增加了除零异常判断。

注意:当前代码已支持基础加减乘除,但尚未处理运算符优先级(如先乘除后加减)。若需支持优先级,需进一步优化为双栈逻辑(一个存数字、一个存运算符,根据优先级判断是否提前计算)。

内容的提问来源于stack exchange,提问作者CarlE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:55:20