中綴表達式:就是目前我們用到的計算表達式 如:“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; } } }