C#資料結構與演算法系列(十):逆波蘭計算器——逆波蘭表示式(字尾表示式)

NO發表於2020-06-21

1.介紹

字尾表示式又稱逆波蘭表示式,與字首表示式相似,只是運算子位於運算元之後

2.舉例說明

(3+4)*5-6對應的字尾表示式就是3 4 +5 * 6 -

3.示例

輸入一個逆波蘭表示式(字尾表示式),使用棧(Stack),計算其結果

思路分析:

從左至右掃描表示式,遇到數字時,將數字壓入堆疊,遇到運算子時,彈出棧頂的兩個數,用運算子對它們做相應的計算(次頂元素 和 棧頂元素),並將結果入棧;

重複上述過程直到表示式最右端,最後運算得出的值即為表示式的結果例如: (3+4)×5-6 對應的字尾表示式就是 3 4 + 5 × 6 - , 

針對字尾表示式求值步驟如下:

從左至右掃描,將3和4壓入堆疊;
遇到+運算子,因此彈出4和3(4為棧頂元素,3為次頂元素),計算出3+4的值,得7,再將7入棧;
將5入棧;
接下來是×運算子,因此彈出5和7,計算出7×5=35,將35入棧;
將6入棧;
最後是-運算子,計算出35-6的值,即29,由此得出最終結果

程式碼實現:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace DataStructure
{
    public class PolandNotation
    {
        public static void Test()
        {
            try
            {
                //定義逆波蘭表示式
                string suffixExpression = "3 4 + 5 * 6 -";

                //將suffixExpression轉換成連結串列的方式
                var list = GetListString(suffixExpression);

                //輸出結果
                var result = Calculate(list);

                Console.WriteLine($"{suffixExpression}的結果是{result}");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
           
        }
        /// <summary>
        /// 獲取集合
        /// </summary>
        /// <param name="suffixExpression"></param>
        /// <returns></returns>
        public static List<string> GetListString(string suffixExpression)
        {
            //首先例項化List
            List<string> list = new List<string>();

            //將字串通過空格切換成陣列
            string[] split=suffixExpression.Split(" ");

            //迴圈新增
            foreach (var item in split)
            {
                list.Add(item);
            }

            return list;
        }

        /// <summary>
        /// 計算
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static int Calculate(List<string> list)
        {
            //建立棧
            Stack<string> stack = new Stack<string>();

            //迴圈遍歷
            list.ForEach(item =>
            {
                //正規表示式判斷是否是數字,匹配的是多位數
                if (Regex.IsMatch(item,"\\d+"))
                {
                    //如果是數字直接入棧
                    stack.Push(item);
                }
                //如果是操作符
                else
                {
                    //出棧兩個數字,並運算,再入棧
                    int num1 =int.Parse(stack.Pop());

                    int num2 = int.Parse(stack.Pop());

                    int result = 0;

                    if(item.Equals("+"))
                    {
                        result = num2 + num1;
                    }
                    else if(item.Equals("*"))
                    {
                        result = num2 * num1;
                    }
                    else if(item.Equals("/"))
                    {
                        result = num2 / num1;
                    }
                    else if (item.Equals("-"))
                    {
                        result = num2 - num1;
                    }
                    else
                    {
                        throw new Exception("無法識別符號");
                    }

                    stack.Push(""+result);
                }
            });

            //最後把stack中資料返回
            return int.Parse(stack.Pop());
        }
    }
}

結果圖:

 

相關文章