zoukankan      html  css  js  c++  java
  • 数据结构和算法-中缀表达式转后缀表达式(c#)

    介绍

    支持数字类型、浮点类型运算表达式运算,看下面的案例

    具体步骤

    1)初始化两个栈:运算符栈s1和储存中间结果的栈s2;
    2)从左至右扫描中缀表达式;
    3)遇到操作数时,将其压s2;
    4)遇到运算符时,比较其与s1栈顶运算符的优先级:
    (1)如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
    (2)否则,若优先级比栈顶运算符的高,也将运算符压入s1;
    (3)否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中新的栈顶运算符相比较;
    5)遇到括号时:
    (1)如果是左括号“(”,则直接压入s1
    (2)如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
    6)重复步骤2至5,直到表达式的最右边
    7)将s1中剩余的运算符依次弹出并压入s2
    8)依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

    客户端

     string expression = "1+((2+3)*40.5)-5.3";
    //结果计算
     var result = PolandNotation.Calculate<float>(expression);
     Console.WriteLine($"{expression}={result}");
    

    助手类

        public class PolandNotation {
            /// <summary>
            /// 计算
            /// </summary>
            /// <param name="list"></param>
            /// <returns></returns>
            public static T Calculate<T>(string expression)
            {
                //将中缀表达式转换成后缀表达式
                List<string> suffixExpression = PolandNotation.ParseSuffixExpression<T>(expression);
    
                //创建栈
                Stack<string> stack = new Stack<string>();
    
                //循环遍历
                suffixExpression.ForEach(item =>
                {
                    string regex = GetRegex<T>();
                    if (Regex.IsMatch(item, regex))//"\d+"
                    {
                        //如果是数字直接入栈
                        stack.Push(item);
                    }
                    //如果是操作符
                    else
                    {
                        //出栈两个数字,并运算,再入栈
                        dynamic num1 = (T)Convert.ChangeType(stack.Pop(),typeof(T));
    
                        dynamic num2 = (T)Convert.ChangeType(stack.Pop(), typeof(T));
    
                        T result = default(T);
    
                        if (item.Equals("+"))
                        {
                            result = num2 + num1;
                        }
                        else if (item.Equals("*"))
                        {
                            result = num2 * num1;
                        }
                        else if (item.Equals("/"))
                        {
                            result = num2 / num1;
                        }
                        else if (item.Equals("-"))
                        {
                            result = num2 - num1;
                        }
                        else
                        {
                            throw new Exception("无法识别符号");
                        }
    
                        stack.Push("" + result);
                    }
                });
    
                //最后把stack中数据返回
                return (T)Convert.ChangeType(stack.Pop(),typeof(T));
            }
    
            /// <summary>
            /// 字符串转中缀表达式的List
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            private static List<string> ToInfixExpression(string expression)
            {
                List<string> list = new List<string>();
    
                int index = 0;
    
                string str = "";
    
                do
                {
    
                    //48-57ASCII码代表的是0-9 如果不是0-9直接入链表
                    if (expression[index] < 48 || expression[index] > 57)//ascii编码
                    {
                        list.Add("" + expression[index]);
    
                        index++;
                    }
                    else
                    {
                        str = "";
    
                        //多位数判断
                        while (index < expression.Length &&( expression[index] >= 48 && expression[index] <= 57|| expression[index]==46))
                        {
    
                            str += expression[index];
    
                            index++;
                        }
    
                        list.Add(str);
                    }
    
                } while (index < expression.Length);
    
                return list;
            }
    
            /// <summary>
            /// 中缀转后缀
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            private static List<string> ParseSuffixExpression<T>(string expression)
            {
               List<string> expressionList = ToInfixExpression(expression);
    
                //存储中间结果
                List<string> list = new List<string>();
                //符号栈
                Stack<string> stack = new Stack<string>();
    
                foreach (var item in expressionList)
                {
                    //多位数判断 如果是数字直接加入list
                    var regex = GetRegex<T>();
                    if (Regex.IsMatch(item, regex))//"\d+"
                    {
                        list.Add(item);
                    }
                    //如果是左括号,直接入符号栈
                    else if (item.Equals("("))
                    {
                        stack.Push(item);
                    }
                    //如果是右括号
                    else if (item.Equals(")"))
                    {
                        //依次弹出stack栈顶的运算符,并存入list,直到遇到左括号为止
                        while (!stack.Peek().Equals("("))
                        {
                            list.Add(stack.Pop());
                        }
                        //将(也出栈
                        stack.Pop();
                    }
                    //如果是*/+-
                    else
                    {
                        //循环判断item的优先级小于或者等于stack栈顶运算符,将stack栈顶的运算符出栈并加入到list中
                        while (stack.Count != 0 && Operation.GetValue(stack.Peek()) >= Operation.GetValue(item))
                        {
                            list.Add(stack.Pop());
                        }
                        //将item入栈
                        stack.Push(item);
                    }
                }
    
                //将stack剩余的运算符依次入list
                while (stack.Count != 0)
                {
                    list.Add(stack.Pop());
                }
    
                return list;
            }
    
            private static string GetRegex<T>()
            {
                string regex = "\d+";
               Type t = typeof(T);
                if (t == typeof(Int16) || t == typeof(Int32) || t == typeof(Int64))
                {
                    regex = "\d+";
                }
                else if (t==typeof(float)|| t == typeof(double) || t == typeof(decimal))
                {
                    regex = "(\d+\.\d+|\d+)";
                }
                return regex;
            }
        }
        public class Operation
        {
            private static int ADD = 1;
            private static int SUB = 1;
            private static int MUL = 2;
            private static int DIV = 2;
    
            public static int GetValue(string operation)
            {
                int result = 0;
    
                switch (operation)
                {
                    case "+":
                        result = ADD;
                        break;
                    case "-":
                        result = SUB;
                        break;
                    case "*":
                        result = MUL;
                        break;
                    case "/":
                        result = DIV;
                        break;
                    default:
                        // Console.WriteLine("不存在该运算符");
                        break;
                }
    
                return result;
            }
        }
    
  • 相关阅读:
    HDU.2899.Strange fuction(牛顿迭代)
    BZOJ.3771.Triple(母函数 FFT 容斥)
    树的实现(2)
    树的练习
    死锁问题
    进程的三种状态
    线程的同步与实现
    进程间通信详解
    进程和线程以及它们的区别
    https协议
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/13290776.html
Copyright © 2011-2022 走看看