中缀表达式:就是目前我们用到的计算表达式 如:“9+(3-1)*3+5/2”
后缀表达式:就是把运算符放置到数字的后面 如:"9 3 1 - 3 * + 5 2 / +"
中缀表达式 转化为后缀表达式规则:
从走到有遍历中缀表达式的数字和字符
若是数字输出,即成为后缀表达式的一部分
若是符号则判断其与栈顶符号的优先级
是右括号或者优先级低于栈顶符号(乘除优先于加减)则栈顶元素一次出栈并输出
并将当前符号进栈
一直到最终输出后缀表达式
后缀表达式如何用计算机得到结果:
从左到右遍历表达式的每个数字和符号,
遇到数字就进栈,
遇到符号就将处于栈顶的两个数字出栈,
进行运算,
运算结果进栈,
一直到最终结果
具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Console_SiZeYunSuanFu { class Program { static void Main(string[] args) { bool temp = true; while (temp) { Console.WriteLine("请输入要计算的表达式:"); string zhongZhuiStr = Console.ReadLine(); Console.Write("表达式" + zhongZhuiStr + "的值为:" + GetValue(GetHouZhuiStr(zhongZhuiStr)).ToString()); if (Console.ReadLine() == "0") { temp = false; } } } /// <summary> /// 得到后缀表达式 /// 规则:从走到有遍历中缀表达式的数字和字符 /// 若是数字输出,即成为后缀表达式的一部分 /// 若是符号则判断其与栈顶符号的优先级 /// 是右括号或者优先级低于栈顶符号(乘除优先于加减)则栈顶元素一次出栈并输出 /// 并将当前符号进栈 /// 一直到最终输出后缀表达式 /// </summary> /// <param name="ZhongZhuiStr">中缀表达式</param> /// <returns>后缀表达式</returns> static string GetHouZhuiStr(string ZhongZhuiStr) { Stack stack = new Stack(); string HouZhuiStr = ""; //循环中缀表达式的每一个字符 for (int i = 0; i < ZhongZhuiStr.Length; i++) { //是数字那么把数字追加到后缀表达式中 if (IsInt(ZhongZhuiStr[i].ToString())) { HouZhuiStr += ZhongZhuiStr[i].ToString(); } else { //栈时空或者符号位(那么把符号 进栈 if (stack.IsEmpty() || ZhongZhuiStr[i].ToString() == "(") { stack.push(ZhongZhuiStr[i]); } else { //符号是 ) if (ZhongZhuiStr[i].ToString() == ")") { bool temp = true; while (temp) { //不断的出栈 并追加到后缀表达式中 直到遇到 ( string str = stack.pop().ToString(); if (str == "(") { break; } HouZhuiStr += str; } continue; } //如果栈不是空那么比较优先级 优先级大 与栈顶元素那么入栈 if (!stack.IsEmpty() && IsYouXian(ZhongZhuiStr[i].ToString(), stack.Top.ToString())) { stack.push(ZhongZhuiStr[i]); } else//如果优先级小那么出栈 直到遇到比其优先级 大的元素 { while (!stack.IsEmpty() && !IsYouXian(ZhongZhuiStr[i].ToString(), stack.Top.ToString())) { HouZhuiStr += stack.pop().ToString(); } //将这个字符入栈 stack.push(ZhongZhuiStr[i]); } } } } //将所有栈中的元素 出栈 追加到 后缀表达式中 while (!stack.IsEmpty()) { HouZhuiStr += stack.pop().ToString(); } return HouZhuiStr; } /// <summary> /// 得到计算的值 /// 规则: /// 从左到右遍历表达式的每个数字和符号, /// 遇到数字就进栈, /// 遇到符号就将处于栈顶的两个数字出栈, /// 进行运算, /// 运算结果进栈, /// 一直到最终结果 /// </summary> /// <param name="houZhuiStr">后缀表达式</param> /// <returns>结果</returns> static decimal GetValue(string houZhuiStr) { Stack stack = new Stack(); for (int i = 0; i < houZhuiStr.Length; i++) { //判断是否是数字,是数字那么进栈 if (IsInt(houZhuiStr[i].ToString())) { stack.push(houZhuiStr[i].ToString()); } else//不是数字那么吧处于站顶端的两个元素出栈,并运算得到结果 { decimal num1 = Convert.ToDecimal(stack.pop().ToString()); decimal num2 = Convert.ToDecimal(stack.pop().ToString()); decimal num3 = 0; if (houZhuiStr[i].ToString() == "+") { num3 = num2 + num1; } else if (houZhuiStr[i].ToString() == "-") { num3 = num2 - num1; } else if (houZhuiStr[i].ToString() == "*") { num3 = num2 * num1; } else if (houZhuiStr[i].ToString() == "/") { num3 = num2 / num1; } //将值保存到栈中 stack.push(num3); } } return Convert.ToDecimal(stack.pop().ToString()); } /// <summary> /// 判断str1是否比str2优先 /// </summary> /// <param name="str1"></param> /// <param name="str2"></param> /// <returns></returns> static bool IsYouXian(string str1, string str2) { // */>+->() if (str1 == "+" || str1 == "-") { return str2 == "(" ? true : false; } else { return str2 == "+" || str2 == "-" || str2 == "(" ? true : false; } } /// <summary> /// 判断是否为int类型 /// </summary> /// <param name="str"></param> /// <returns></returns> static bool IsInt(string str) { try { Convert.ToInt32(str); } catch { return false; } return true; } } /// <summary> /// 栈 /// </summary> class Stack { public class Node { public object Data { get; set; } public Node NextNode { get; set; } public Node(object o) { Data = o; } public override string ToString() { return this.Data.ToString(); } } /// <summary> /// 指向栈顶元素 /// </summary> public Node Top { get; set; } /// <summary> /// 指向栈顶元素的下一个元素 /// </summary> public Node Bottom { get; set; } /// <summary> /// 构造方法 /// </summary> public Stack() { Node node = new Node(null); Bottom = node; Top = node; } /// <summary> /// 进栈 /// </summary> public void push(object data) { Node node = new Node(data); node.NextNode = Top; Top = node; } /// <summary> /// 出栈 /// </summary> /// <returns></returns> public object pop() { Node node = Top; Top = Top.NextNode; return node.Data; } /// <summary> /// 栈空 /// </summary> /// <returns></returns> public bool IsEmpty() { return Top == Bottom; } } }