导读:本期聚焦于小伙伴创作的《C#怎么实现简单的计算器功能?如何解析数学表达式字符串》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么实现简单的计算器功能?如何解析数学表达式字符串》有用,将其分享出去将是对创作者最好的鼓励。

在C#中实现简单计算器功能的核心是正确解析用户输入的数学表达式字符串,比如处理"3+5*2"这类包含不同优先级运算符的表达式,需要按照运算规则拆分计算,而不是从左到右直接累加。

C#怎么实现简单的计算器功能?如何解析数学表达式字符串

核心实现思路

数学表达式解析的常用方案是使用双栈结构,一个栈存储数字,一个栈存储运算符,遍历表达式字符串时按照规则入栈、出栈计算,具体规则如下:

  • 遇到数字时,提取完整的连续数字(支持多位数)
  • 遇到运算符时,比较当前运算符和栈顶运算符的优先级,栈顶优先级更高则先计算栈顶的运算
  • 表达式遍历完成后,将栈中剩余的运算符依次计算
  • 括号作为特殊运算符处理,左括号直接入栈,遇到右括号时计算到左括号为止

优先级定义

我们先定义运算符的优先级,加减优先级为1,乘除优先级为2,括号单独处理:

// 定义运算符优先级
private static int GetPriority(char op)
{
    switch (op)
    {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}

完整计算器实现代码

下面是完整的表达式解析和计算代码,支持加减乘除和括号运算:

using System;
using System.Collections.Generic;

public class SimpleCalculator
{
    // 判断字符是否为运算符
    private static bool IsOperator(char c)
    {
        return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
    }

    // 获取运算符优先级
    private static int GetPriority(char op)
    {
        switch (op)
        {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
            default:
                return 0;
        }
    }

    // 执行单次运算
    private static double Calculate(double num1, double num2, char op)
    {
        switch (op)
        {
            case '+':
                return num1 + num2;
            case '-':
                return num1 - num2;
            case '*':
                return num1 * num2;
            case '/':
                if (num2 == 0)
                {
                    throw new DivideByZeroException("除数不能为0");
                }
                return num1 / num2;
            default:
                return 0;
        }
    }

    // 解析并计算数学表达式
    public static double CalculateExpression(string expression)
    {
        // 数字栈
        Stack<double> numStack = new Stack<double>();
        // 运算符栈
        Stack<char> opStack = new Stack<char>();

        int i = 0;
        while (i < expression.Length)
        {
            char c = expression[i];
            // 跳过空格
            if (c == ' ')
            {
                i++;
                continue;
            }

            // 处理数字
            if (char.IsDigit(c) || c == '.')
            {
                string numStr = "";
                // 提取完整的数字(支持小数)
                while (i < expression.Length && (char.IsDigit(expression[i]) || expression[i] == '.'))
                {
                    numStr += expression[i];
                    i++;
                }
                if (double.TryParse(numStr, out double num))
                {
                    numStack.Push(num);
                }
                continue;
            }

            // 处理左括号
            if (c == '(')
            {
                opStack.Push(c);
                i++;
            }
            // 处理右括号
            else if (c == ')')
            {
                // 计算到左括号为止
                while (opStack.Peek() != '(')
                {
                    char op = opStack.Pop();
                    double num2 = numStack.Pop();
                    double num1 = numStack.Pop();
                    numStack.Push(Calculate(num1, num2, op));
                }
                // 弹出左括号
                opStack.Pop();
                i++;
            }
            // 处理运算符
            else if (IsOperator(c))
            {
                // 比较优先级,栈顶运算符优先级更高则先计算
                while (opStack.Count > 0 && GetPriority(opStack.Peek()) >= GetPriority(c))
                {
                    char op = opStack.Pop();
                    double num2 = numStack.Pop();
                    double num1 = numStack.Pop();
                    numStack.Push(Calculate(num1, num2, op));
                }
                opStack.Push(c);
                i++;
            }
            else
            {
                throw new ArgumentException($"表达式包含非法字符: {c}");
            }
        }

        // 处理栈中剩余的运算
        while (opStack.Count > 0)
        {
            char op = opStack.Pop();
            double num2 = numStack.Pop();
            double num1 = numStack.Pop();
            numStack.Push(Calculate(num1, num2, op));
        }

        return numStack.Pop();
    }
}

使用示例

调用上面的计算器类进行计算:

class Program
{
    static void Main(string[] args)
    {
        string expression1 = "3+5*2";
        string expression2 = "(3+5)*2";
        string expression3 = "10-2*3+8/4";

        Console.WriteLine($"{expression1} = {SimpleCalculator.CalculateExpression(expression1)}");
        Console.WriteLine($"{expression2} = {SimpleCalculator.CalculateExpression(expression2)}");
        Console.WriteLine($"{expression3} = {SimpleCalculator.CalculateExpression(expression3)}");
    }
}

上述代码运行后会输出正确结果,分别是13、16、6,符合数学运算规则。

注意事项

  • 当前实现仅支持非负数字,若需要支持负数,可以在表达式开头或左括号后添加负号处理逻辑
  • 代码中没有处理除数为0的情况,实际使用时可以根据需求添加更友好的异常提示
  • 如果表达式格式错误(比如括号不匹配),会抛出异常,实际项目中可以添加表达式合法性校验逻辑

C#数学表达式解析计算器实现字符串处理修改时间:2026-06-28 16:30:20

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。