using System; using System.Collections.Generic; using System.Text; namespace HJ54 { /// <summary> /// 1.用两个栈分别压数字和运算符; /// 2.如果当前运算符优先级('*/')高于栈顶运算符('+-')优先级,则将运算符入栈; /// 3.反之,从数字栈中弹出两个数,从运算符栈中弹出栈顶运算符,进行运算,数字栈压入运算结果,符号栈压入当前运算符。 /// 4..出现左括号,则直接压入;出现右括号,则从数字栈中弹出两个数,从运算符栈中弹出栈顶运算符,进行运算,数字栈压入运算结果,重复该操作直到栈顶弹出左括号为止。 /// </summary> internal class Program { static void Main(string[] args) { string str = Console.ReadLine(); str = str.Replace('{', '(').Replace('}', ')').Replace('[', '(').Replace(']', ')'); //外面加一层()不影响结果,方便后面计算能够遍历完整,同时能防止最后一个数字无法提取压入数据栈 str = $"({str})"; char[] chars = str.ToCharArray(); Stack<int> numbers = new Stack<int>(); StringBuilder sb = new StringBuilder(); Stack<char> ops = new Stack<char>(); for (int i = 0; i < chars.Length; i++) { char curChar = chars[i]; #region 这一段用于将数字提取出来 if (!char.IsDigit(curChar) && sb.Length > 0) { if (int.TryParse(sb.ToString(), out int num)) { numbers.Push(num); sb.Clear(); } } //判断是否为负号 if (curChar == '-') { //当i == 0时,-表示负号 if (i == 0) { sb.Append(curChar); //注意返回,进入下一个循环,防止-既被当作是负号又当作减号 continue; } char lastChar = chars[i - 1]; //当前面是+-*/(时,-表示负号 if (lastChar == '+' || lastChar == '-' || lastChar == '*' || lastChar == '/' || lastChar == '(') { sb.Append(curChar); //注意返回,进入下一个循环,防止-既被当作是负号又当作减号 continue; } } if (char.IsDigit(curChar)) { sb.Append(curChar); continue; } #endregion if (curChar == '(') { ops.Push(curChar); continue; } if (curChar == '+' || curChar == '-' || curChar == '*' || curChar == '/') { while (true) { if (ops.Count == 0 || numbers.Count < 2) { break; } char topOpt = ops.Peek(); //扫描到当前运算符时,如果当前运算符栈顶运算符可用运算, //则进行运算,直到不满足运算条件为止 if (CanCal(topOpt, curChar)) { char opt = ops.Pop(); int num02 = numbers.Pop(); int num01 = numbers.Pop(); numbers.Push(Cal(num01, num02, opt)); } else { break; } } ops.Push(curChar); continue; } if (curChar == ')') { while (true) { if (ops.Count == 0 || numbers.Count < 2) { break; } char opt = ops.Pop(); if (opt == '(') { break; } int num02 = numbers.Pop(); int num01 = numbers.Pop(); numbers.Push(Cal(num01, num02, opt)); } } } Console.WriteLine(numbers.Peek()); } /// <summary> /// 判断扫描到当前运算符时,运算符栈顶运算符是否可用于计算运算 /// </summary> static bool CanCal(char topChar, char curChar) { //如果当前运算符栈顶符是左括号时,不可运算,因为括号是不能进行运算的 if (topChar == '(') { return false; } //如果当前运算符栈顶符是*/ //当前扫描到运算符也+-,可运算,*/优先级比+-高, //当前扫描到运算符是*/,可运算,同等优先级的运算符从左到右计算 if (topChar == '*' || topChar == '/') { return true; } //如果当前运算符栈顶符是+-,并且当前扫描到运算符也是+-,可运算,同等优先级的运算符从左到右计算 return curChar == '+' || curChar == '-'; } static int Cal(int num01, int num02, char opt) { switch (opt) { case '+': return num01 + num02; case '-': return num01 - num02; case '*': return num01 * num02; case '/': return num01 / num02; default: return 0; } } } }