小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

基于堆棧的計算器實現(xiàn)算法

 todaytomo 2006-12-30

    對于計算器,有很多成熟的理論。本文章討論的是利用一個操作數(shù)堆棧和一個運算符堆棧進行運算的方法。這種算法已經(jīng)有很完善的解決方案,此處討論的是最簡化 的模型,旨在讓初學者在最短的時間內(nèi)學到此算法的精髓,并能靈活的應用到科研的任何一個領(lǐng)域。

簡單表達式的計算

      首先請看這個表達式:
      3+5+6*7*8^2^3 (8^2指的是82)
      這里運算有三種優(yōu)先級“^”-->
“*”-->“+”, 如何實現(xiàn)優(yōu)先級運算呢?

      當掃描字符串3+5+6*7*8^2^3的時候。

      1. 先移進3+5,發(fā)現(xiàn)下一個運算符是+,優(yōu)先級與上一個相同,于是就先計算3+5,將它們改為8。于是式子變?yōu)椋?+6*7*8^2^3
      2. 現(xiàn)在下一運算符*優(yōu)先級比上一個+要高,于是繼續(xù)前移:8+6*7*8^2^3
      3. 現(xiàn)在下一個運算符是*,與上一個相同,于是先計算6*7,式子變?yōu)椋?+42*8^2^3
      4. 繼續(xù):8+42*8^2^3
      5. 8+42*64^3
      6. 8+42*262144
      7. 8+1.101*107
      8. 1.101*107

     現(xiàn)在式子變成一個數(shù),整個運算也就結(jié)束了。

     但怎樣在計算機中完成這個過程呢?當遇到8+6*7時必須先運算6*7,但這時8和+保存在哪里呢?這里使用的方法是:建立一個操作數(shù)堆棧和一個運算符堆棧,把8和+分別壓到兩個堆棧中。
     對于式子:3+5+6*7-8^2

剩余式子        操作數(shù)堆棧 運算符堆棧 優(yōu)先級比較         操作
3+5+6*7-8^2
±6*7 -8^2     3,5            ±               相等    計算 3+5=8
+6*7-8^2     8
*7 -8^2        8,6            ±               大于
-8^2           8,6,7         +,*           小于    計算6*7=42
-8^2            8,42           +               等于    計算 8+42=50
-8^2           50
^2             50,8           -                大于
                50,8,2        -,^                     計算8^2=64
                50,64          -                        計算 50-64=-14
                -14             ^
--------------------------------------------------------------------------------------------------------------
    可以看出,如果利用操作數(shù)堆棧和運算符堆棧的話,只要:
    1. 步進掃描表達式。
    2. 遇到操作數(shù)就壓入操作數(shù)堆棧中,遇到運算符就將它的優(yōu)先級與運算符堆棧棧頂運算符的優(yōu)先級比較,如果它的優(yōu)先級更大,就將它壓入堆棧,否則就將棧頂運算符彈出來進行運算。
    只要這樣就可以實現(xiàn)優(yōu)先級的運算。

優(yōu)先級的改變

在我的示例程序中規(guī)定了3種優(yōu)先級

      +、-、自反運算(-x,-y,-z,-1,-2) :優(yōu)先級為
1(較低)
      *、/?。簝?yōu)先級為2
      ^ :優(yōu)先級為3(最高)

      但“(”的優(yōu)先級應該是多少,括號指的是開始一個新的運算,對于3+5*(6-2),當掃描到“(”時,原先的
優(yōu)先級就全部失效了,一切需要重新計算,因此掃描時遇到“(”,就將它無條件壓入棧中,同時置最低優(yōu)先級-
      1。與此操作相同的還有 “sin(”、“cos(”、“tan(”、“tg(”、“lg(”、“ln(”等.
      遇到“)”,就應該不停出棧運算直至找到“(”、“sin(”、“cos(”、“tan(”、“tg(”、“lg(”、“ln(”等。

程序流程

      對于一個合法的簡單數(shù)學表達式,肯定是一個操作數(shù)跟著一個運算符,第一個和最后一個都是操作數(shù)。因此最簡單的程序編寫方法就是寫一個取操作數(shù)的程序 CCalc::GetOperand(),再寫一個取運算符的程序CCalc::GetOperator(),然后循環(huán)執(zhí)行。

while(!GetOperand()&&!GetOperator()&&!vError);

這樣就可以計算出最終的結(jié)果。

      1. 取操作數(shù)GetOperand():
    (1)取操作數(shù)時首先遇到的不一定就是操作數(shù)本身,而可能是“(”、“sin(”、“cos(”、“tan(”、“tg(”、“lg(”、“ln(”或自反運算符“-”或無意義的“+”號,首先將它們壓入運算符棧中。
    (2)然后檢查是不是“x”、“y”、“z”等變量或“PI”等常量,有的話將它們的值壓到操作數(shù)棧中。
    (3)如果不是變量或常量,則檢查數(shù)的合法性,如果不是合法數(shù),就退出全部運算。

      2.取運算符GetOperator():
    (1)取運算符時首先遇到的不一定就是運算符,而可能是“)”,先要對它進行處理。
    (2)然后檢查是不是掃描到了最后,如果是就清棧輸出結(jié)果。
    (3)取出新運算符并給它對應的優(yōu)先級。
    (4)如果運算符堆棧不為空,從中彈出一個運算符,比較優(yōu)先級,如果新的運算符優(yōu)先級小于等于彈出運算符優(yōu)先級,就把彈出運算符重新壓回去,否則對彈出運算符進行運算。
    (5)將新運算符壓入堆棧中。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=284095

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多