演算法手記(2)Dijkstra雙棧算術運算式求值演算法

來源:互聯網
上載者:User

標籤:style   blog   color   io   os   ar   strong   for   div   

這兩天看到的內容是關於棧和隊列,在棧的模組發現了Dijkstra雙棧算術運算式求值演算法,可以用來實現計算機類型的app。

程式設計語言系統一般都內建了對算術運算式的處理,但是他們是如何在內部實現的呢?為了瞭解這個過程,我們可以自行搭建一套簡易的算術運算式處理機制,這裡就用到棧特性和本篇提到的Dijkstra演算法。

 

概述:
     算術運算式可能是一個數、或者是由一個左括弧、一個算術運算式、一個運算子、另一個算術運算式和一個右括弧組成的運算式。為了簡化問題,這裡定義的是未省略括弧的算術運算式,它明確地說明了所有運算子的運算元,形式如下:

                                                                  (1+((2+3)*(4*5)))

 

思路:

     運算式由括弧、運算子和運算元構成,我們根據以下4中情況從左至右逐個將這些實體送入棧處理:

     1.將運算元壓入運算元棧;

     2.將運算子壓入運算子棧;

     3.忽略左括弧;

     4.在遇到右括弧時,彈出一個運算子,彈出所需數量的運算元,並將運算後的結果壓入運算元棧;

    在處理完最後一個右括弧時,運算元棧上只會剩下一個值,它就是運算式的計算結果。這種方法咋一看難理解,但要證明它能計算得到正確的值很簡單:

    每當演算法遇到一個括弧包圍,並由一個運算子和兩個運算元組成的子式時,他都將運算子和運算元運算結果壓入運算元棧。這樣的結果就像是在輸入中用這個值代替了該子運算式,因此用這個值代替子運算式得到的結果和原運算式相同。我們可以反覆應用這個規律並得到一個最終值。

例如:

(1+((2+3)*(4*5)))

(1+(5*(4*5)))

(1+(5*20))

(1+100)

  101

 

代碼實現:


這裡我採用C#來實現,最終運行效果完全符合預期,證明了此演算法的正確性,代碼如下:

using System;using System.Collections.Generic;using System.Linq;namespace Evaluate{    class Program    {        static void Main(string[] args)        {            string testExpress = "(1+((2+3)*(4*5)))";            Console.WriteLine(Evaluate(testExpress));        }        //DijkStra        static double Evaluate(string express)        {            var expressChars = express.ToArray<char>();            Stack<char> ops = new Stack<char>();            Stack<double> vals = new Stack<double>();            if (express.Length > 0)            {                foreach (var opt in expressChars)                {                    switch (opt)                    {                        case ‘+‘:                        case ‘-‘:                        case ‘*‘:                        case ‘/‘:                            ops.Push(opt);                            break;                        case ‘)‘:                            var op = ops.Pop();                            var v = vals.Pop();                            switch (op)                            {                                case ‘+‘:                                    v += vals.Pop();                                    break;                                case ‘-‘:                                    v = vals.Pop() - v;                                    break;                                case ‘*‘:                                    v *= vals.Pop();                                    break;                                case ‘/‘:                                    v = vals.Pop() / v;                                    break;                            }                            vals.Push(v);                            break;                        case ‘ ‘:                        case ‘(‘:                            break;                        default:                            vals.Push(double.Parse(opt.ToString()));                            break;                    }                }                return vals.Pop();            }            return double.MaxValue;        }    }}

 

總結:

Dijkstra演算法充分利用了棧的特性,具備較高的執行效率,經過進一步的擴充修改,就完全可以實現具備科學計算功能的複雜計算類app。如果大家還有更好的,更適用的演算法,歡迎在評論中給出地址,謝謝。

演算法手記(2)Dijkstra雙棧算術運算式求值演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.