棧的應用-四則運算表達式求值


 

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

 

 

-----------------------------

天王蓋地虎小說網:http://www.twgdh.com/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM