通过Stack实现加减乘除

1 篇文章 0 订阅
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStructure
{
    class StackDemo
    {
        static void Main(string[] args)
        {
            //  TreeNodeTest();
            string infix = "2+3*4*(6+8)*2";  // 中缀
            string suffix = InfixChangeSuffix(infix); // 中缀转后缀
            Console.WriteLine("====suffix======" + suffix);
            double result = CalcSuffix(suffix.Split(',').ToArray());
            Console.WriteLine(result);
            Console.ReadLine();
        }

        /// <summary>
        /// 中缀转后缀
        /// </summary>
        /// <param name="infixExpression">中缀表达式</param>
        /// <returns></returns>
        static string InfixChangeSuffix(string infixExpression)
        {
            string suffix = string.Empty;
            string completeDigits = string.Empty;
            Stack<char> stack = new Stack<char>();

            for (int i = 0; i < infixExpression.Length; i++)
            {
                if (IsOperator(infixExpression[i])) // 是否是运算符
                {
                    if (!String.IsNullOrWhiteSpace(completeDigits))
                    {
                        suffix += completeDigits + ",";  // 把前面的数字加入到后缀表达式里
                        completeDigits = string.Empty;   // 清空,待下次继续使用
                    }

                    if (stack.Count > 0)  // 如果栈里有元素,则判断当前符号与栈顶元素的优先级
                    {
                        char stackTopSymbol;
                        if (infixExpression[i] == '(') // 如果是左括号则直接进栈
                        {
                            stack.Push(infixExpression[i]);
                        }
                        else if (infixExpression[i] == ')')  // 如果是右括号,则出栈直到遇到左括号为止
                        {
                            stackTopSymbol = stack.Pop();  // 弹出栈顶元素
                            do
                            {
                                if (stackTopSymbol != '(') suffix += Convert.ToString(stackTopSymbol) + ",";
                                if (stack.Count > 0) stackTopSymbol = stack.Pop();
                                else break;  // 中缀表达式有异常即四则运算不符合数学规则
                            } while (stackTopSymbol != '('); // 直到遇到左括号为止则停止出栈
                        }
                        else
                        {
                            stackTopSymbol = stack.Peek();  // 拿栈顶元素出来,但不移除
                            int curPriority = Priority(infixExpression[i]);
                            int stackTop = Priority(stackTopSymbol);

                            if (curPriority <= stackTop)
                            {
                                do
                                {
                                    suffix += stackTopSymbol + ",";
                                    stack.Pop(); // 栈顶元素优先级高当前符号,则弹出来
                                    if (stack.Count > 0)
                                    {
                                        stackTopSymbol = stack.Peek();// 拿栈顶元素出来,但不移除
                                        stackTop = Priority(stackTopSymbol);
                                    }
                                    else break;  // 原理同上

                                } while (curPriority <= stackTop);
                            }

                            stack.Push(infixExpression[i]);  // 当前的运算符入栈
                        }
                    }
                    else
                    {
                        stack.Push(infixExpression[i]);
                    }
                }
                else
                {
                    completeDigits += Convert.ToString(infixExpression[i]);
                }
            }

            suffix += completeDigits + ",";

            while (stack.Count > 0)
            {
                suffix += Convert.ToString(stack.Pop()) + ",";
            }
            return suffix;
        }

        /// <summary>
        /// 运算符符号优先级
        /// </summary>
        /// <param name="symbol">运算符符号</param>
        /// <returns></returns>
        static int Priority(char symbol)
        {
            switch (symbol)
            {
                case '*':
                case '/':
                    return 2;
                case '+':
                case '-':
                    return 1;
            }
            return -1;
        }

        static double Calc(double first, double second, char symbol)
        {
            switch (symbol)
            {
                case '*':
                    return (double)first * second;
                case '/':
                    return (double)first / second;
                case '+':
                    return (double)first + second;
                case '-':
                    return (double)first - second;
            }

            return 0.0d;

        }

        static bool IsOperator(char symbol)
        {
            char[] symbols = { '+', '-', '*', '/', '(', ')' };
            return symbols.Contains(symbol);
        }

        /// <summary>
        /// 计算后缀表达式结果
        /// </summary>
        /// <param name="suffixExpression"></param>
        /// <returns></returns>
        static double CalcSuffix(string[] suffixExpression)
        {
            Stack<double> stack = new Stack<double>();
            double temp;

            for (int i = 0; i < suffixExpression.Length; i++)
            {
                if (String.IsNullOrWhiteSpace(suffixExpression[i])) break;
                if (double.TryParse(suffixExpression[i], out temp))  // 是数字
                {
                    stack.Push(temp);
                }
                else  // 是运算符
                {
                    double rightNum = stack.Pop();
                    double leftNum = stack.Pop();
                    double result = Calc(leftNum, rightNum, Convert.ToChar(suffixExpression[i]));
                    stack.Push(result);
                }
            }

            return stack.Pop();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值