美文网首页
栈的应用无括号算术表达式求值问题

栈的应用无括号算术表达式求值问题

作者: 周末的游戏之旅 | 来源:发表于2019-08-03 10:29 被阅读0次

问题

计算无括号算术表达式的值

问题分析

运算符优先级:

设置#代表表达式结束标志。

符号 符号 符号
+- */ **
0 1 3

算法原理:

例如:1+1*2
设置两个栈:number(运算数栈)、symbol(运算符栈)
对输入的字符自左向右扫描,进行如下处理:
遇到运算数则进number栈;
遇到运算符则与symbol栈的栈顶元素进行优先级比较:
若栈顶元素的优先级大于当前符号的优先级,则symbol退栈一次,的得到运算符,number栈退栈两次,得到两个运算数,将计算结果压入栈中。再将当前符号压入栈中。
否则,直接将符号压入栈中。


实现

Node

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinkStack
{
    class Node<T>
    {
        T data;
        Node<T> next;
        
        /// <summary>
        /// 构造器
        /// </summary>
        public Node()
        {
            this.Data = default(T);
            this.Next = null;
        }

        /// <summary>
        /// 构造器
        /// </summary>
        /// <param name="data"></param>
        public Node(T data)
        {
            this.Data = data;
        }

        public T Data { get => data; set => data = value; }
        internal Node<T> Next { get => next; set => next = value; }
    }
}

LinkStack

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinkStack
{
    class LinkStack<T>
    {
        Node<T> top;

        public LinkStack()
        {
            this.top = new Node<T>();
        }

        /// <summary>
        /// 入栈
        /// </summary>
        /// <param name="data"></param>
        public void Push(T data)
        {
            //新建节点 
            Node<T> tmp = new Node<T>(data);
            //挂载节点
            tmp.Next = this.top.Next;
            this.top.Next = tmp;
        }

        /// <summary>
        /// 出栈
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            if (top.Next == null) return default(T);

            //保存栈顶节点
            Node<T> tmp = top.Next;
            //悬空栈顶节点
            top.Next = top.Next.Next;
            return tmp.Data;
        }

        /// <summary>
        /// 判空
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            if (this.top.Next == null) return true;
            return false;
        }

        /// <summary>
        /// 读栈顶
        /// </summary>
        /// <returns></returns>
        public T ReadTop()
        {
            return top.Next.Data;
        }
    }
}

Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace LinkStack
{
    class Program
    {
        static void Main(string[] args)
        {
            LinkStack<int> number = new LinkStack<int>();
            LinkStack<string> symbol = new LinkStack<string>();

            string input = Console.ReadLine();

            string numberTmp = "";
            string symbolTmp = "";
            Regex regex = new Regex(@"[0-9]");
            //遍历如果是数字,则缓存,当不是数字时,将缓存入栈并清空缓存
            for (int i = 0; i < input.Length; i++)
            {
                //输入数字
                if (regex.IsMatch(input[i] + ""))
                {
                    //缓存数字
                    numberTmp += input[i];

                    //高优先级计算
                    if (!symbol.IsEmpty() && SymbolMatch(symbol.ReadTop(), symbolTmp))
                    {
                        int num1 = number.Pop();
                        int num2 = number.Pop();
                        number.Push(Calculate(num1,num2,symbolTmp));
                    }
                    
                    //符号入栈
                    if (!symbolTmp.Equals(""))
                    {
                        symbol.Push(symbolTmp);
                    }
                    symbolTmp = "";
                }
                else if (input[i]!='#')
                //输入符号 
                {
                    string s = input[i] + "";
                    symbolTmp += s;
                    //数字入栈
                    number.Push(int.Parse(numberTmp));
                    numberTmp = "";
                }else
                {

                    number.Push(int.Parse(numberTmp));
                    int total = 0;
                    while (!symbol.IsEmpty())
                    {
                        total += Calculate(number.Pop(), number.Pop(), symbol.Pop());
                    }
                    Console.WriteLine(total);
                }
            }
        }

        /// <summary>
        /// 符号优先级判断
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <returns></returns>
        static bool SymbolMatch(string s1, string s2)
        {
            Dictionary<string, int> dic = new Dictionary<string, int>() {
                { "*",2},
                { "/",2},
                { "+",1},
                { "-",1},
                { "#",0}
            };
            return dic[s1] > dic[s2];
        }

        /// <summary>
        /// 计算
        /// </summary>
        /// <returns></returns>
        static int Calculate(int num1,int num2,string symbol)
        {
            int num=0;
            switch (symbol)
            {
                case "*":
                    num= num1 * num2;
                    break;
                case "/":
                    num= num1 / num2;
                    break;
                case "+":
                    num= num1 + num2;
                    break;
                case "-":
                    num= num1 - num2;
                    break;
            }
            return num;
        }

    }
}

相关文章

网友评论

      本文标题:栈的应用无括号算术表达式求值问题

      本文链接:https://www.haomeiwen.com/subject/xuzddctx.html