0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

如何利用棧去實現(xiàn)一種簡單計算器

工程師鄧生 ? 來源:博客園 ? 作者:pdudos ? 2022-09-19 10:32 ? 次閱讀

1. 中綴表達式 和 后綴表達式

中綴表達式: 顧名思義,操作符在操作數(shù)的中間,例如: 1 + 1

后綴表達式: 指操作符在操作后后面 ,例如 1 1 + , 就代表 中綴表達式 的 1 + 1

2. 關于數(shù)據(jù)結(jié)構(gòu): 棧

棧就是一個先進先出的隊列

C語言函數(shù)之間調(diào)用,就是使用棧進行的

3. 中綴表達式 如何利用棧 轉(zhuǎn)換為后綴表達式

利用棧轉(zhuǎn)換規(guī)則如下

遍歷中綴表達式

判斷為數(shù)字直接輸出

判斷為(入棧

判斷為)則,出棧 直至遇到(

判斷為 * 或/

4.1 判斷棧頂元素是否是 * 或/, 如果是 則出棧

4.2 若1不符合規(guī)則,再將這個字符入棧

5.1 判斷棧頂元素是否是 * 或/,如果是,則全部出棧,然后再入棧

5.2 若1不符合,再將這個字符入棧

判斷為+-,則

若表達式計算完畢,將出棧所有數(shù)據(jù)

實際例子

通過棧,將式子3+2(9+8)/3(3/5)轉(zhuǎn)換為后綴表達式

開始式子:3+2*(9+8)/3*(3/5)

開始處理: 3
執(zhí)行規(guī)則1,是數(shù)字直接輸出

輸出:3

:

開始處理: +
執(zhí)行規(guī)則 5.2 直接入棧

輸出:3

:+

開始處理: 2
執(zhí)行規(guī)則1,是數(shù)字直接輸出

輸出:32

:+

開始處理: *
執(zhí)行規(guī)則4.2,直接入棧

輸出:32

:+*

開始處理: (
執(zhí)行規(guī)則2,直接入棧

輸出:32

:+*(

開始處理: 9
執(zhí)行規(guī)則1,直接入棧

輸出:329

:+*(

開始處理: +
執(zhí)行規(guī)則5.2,直接入棧

輸出:329

:+*(+

開始處理: 8
執(zhí)行規(guī)則1,直接入棧

輸出:3298

:+*(+

開始處理: )
執(zhí)行規(guī)則3,出棧直至遇到 (

輸出:3298+

:+*

開始處理: /
執(zhí)行規(guī)則4.1,將棧頂元素為*或/直接出棧,然后在入棧該操作符

輸出:3298+*

:+/

開始處理: 3
執(zhí)行規(guī)則1,直接入棧

輸出:3298+*3

:+/

開始處理: *
執(zhí)行規(guī)則4.1,將棧頂元素為*或/直接出棧,然后在入棧該操作符

輸出:3298+*3/

:+*

開始處理: (
執(zhí)行規(guī)則2,直接入棧

輸出:3298+*3/

:+*(

開始處理: 3
執(zhí)行規(guī)則1,直接入棧

輸出:3298+*3/3

:+*(

開始處理: /
執(zhí)行規(guī)則4.2,入棧

輸出:3298+*3/3

:+*(/

開始處理: 5
執(zhí)行規(guī)則1,直接入棧

輸出:3298+*3/35

:+*(/

開始處理: )
執(zhí)行規(guī)則3,出棧 直至遇到(

輸出:3298+*3/35/

:+*

開始處理: )
執(zhí)行規(guī)則6,全部出棧

輸出:3298+*3/35/*+

:

得到中綴表達式:3298+*3/35/*+

完畢

轉(zhuǎn)換代碼 C語言實現(xiàn):

# include 

int main() {
    // 中綴表達式
    char formula[] = "3+2*(9+8)/3*(3/5)";

    // 棧
    char options[sizeof(formula) * sizeof(char)];
    int stackLen = -1;
    
    printf("%s
",formula);

    int i;
    for (i = 0; formula[i]!='?'; i++) {
        // 規(guī)則1
        if (formula[i] >= '0' && formula[i] <= '9') {
            printf("%c",formula[i]);
        }

        switch (formula[i]) {
            // 規(guī)則2
            case '(': {
                stackLen += 1;
                options[stackLen] =formula[i];
                break;
            }

            // 規(guī)則3
            case ')': {
                while (stackLen >= 0 &&  (options[stackLen] != '(')) {
                    printf("%c",options[stackLen]);
                    stackLen -= 1;
                }
                stackLen-=1;
                break;
            }

            // 規(guī)則4
            case '*':
            case '/': {
                while (stackLen >= 0 && (options[stackLen] == '*' || options[stackLen] == '/')) {
                    printf("%c",options[stackLen]);
                    stackLen -= 1;
                }
                stackLen += 1;
                options[stackLen] = formula[i];
                break;
            }

            // 規(guī)則5
            case '+': 
            case '-': {
                if (stackLen >= 0 &&  (options[stackLen] == '*' || options[stackLen] == '/')) {
                    while (stackLen >= 0) {
                        printf("%c",options[stackLen]);
                        stackLen -= 1;
                    }
                }
                stackLen += 1;
                options[stackLen] = formula[i];
                break;
            }
        }
    }

    // 規(guī)則6 
    while (stackLen >= 0) {
        printf("%c",options[stackLen]);
        stackLen--;
    }

    printf("
");
}

執(zhí)行結(jié)果

# gcc calTest1.c
# ./a.out
3+2*(9+8)/3*(3/5)
3298+*3/35/*+
#

4. 利用棧 后綴表達式計算結(jié)果

利用棧計算后綴表達式規(guī)則如下

假設后綴表達式是有效的

遍歷后綴表達式

判斷為數(shù)字,則進行壓棧

判斷為操作符(+ - * /)

2.1 出棧2個元素,m 和 n (對于當前棧而言,m: 棧頂元素 n: 棧頂?shù)诙€元素)

2.2 計算 n操作符m ,然后將結(jié)果 入棧

實際例子

通過棧,將計算后綴表達式3298+*3/35/*+的值

式子:3298+*3/35/*+

開始處理: 3

執(zhí)行規(guī)則1: 直接入棧

:3

開始處理: 2

執(zhí)行規(guī)則1: 直接入棧

:3 2

開始處理: 9

執(zhí)行規(guī)則1: 直接入棧

:3 2 9

開始處理: 8

執(zhí)行規(guī)則1: 直接入棧

:3 2 9 8

開始處理: +

執(zhí)行規(guī)則2: 取出2個元素,m:8 n:9, 并且執(zhí)行結(jié)果(n + m)入棧

:3 2 17

開始處理: *

執(zhí)行規(guī)則2: 取出2個元素,m:17 n:2, 并且執(zhí)行結(jié)果(n * m)入棧

:3 34

開始處理: 3

執(zhí)行規(guī)則1: 直接入棧

:3 34 3

開始處理: /

執(zhí)行規(guī)則2: 取出2個元素,m:3 n:34, 并且執(zhí)行結(jié)果(n / m)入棧

:3 11.3

開始處理: 3

執(zhí)行規(guī)則1: 直接入棧

:3 11.3 3

開始處理: 5

執(zhí)行規(guī)則1: 直接入棧

:3 11.3 3 5

開始處理: /

執(zhí)行規(guī)則2: 取出2個元素,m:5 n:3, 并且執(zhí)行結(jié)果(n / m)入棧

:3 11.3 0.6

開始處理: *

執(zhí)行規(guī)則2: 取出2個元素,m:0.6 n:11.3, 并且執(zhí)行結(jié)果(n * m)入棧

:3 6.8

開始處理: +

執(zhí)行規(guī)則2: 取出2個元素,m:6.8 n:3, 并且執(zhí)行結(jié)果(n + m)入棧

:9.8

計算結(jié)果:9.8

完成

用C實現(xiàn)該代碼

轉(zhuǎn)換代碼 C語言實現(xiàn):

# include 

int main() {
    // 后綴表達式
    char formula[] = "3298+*3/35/*+";

    // 棧
    float options[sizeof(formula) * sizeof(char)];
    int stackLen = -1;
    
    printf("%s
",formula);

    int i;
    for(i=0;formula[i]!='?';i++) {
        // 規(guī)則1
        if (formula[i] >= '0' && formula[i] <= '9') {
            stackLen++;
            options[stackLen] = (float)(formula[i]-48);
        } else {
            // 規(guī)則2
            float m = options[stackLen];
            stackLen--;

            float n = options[stackLen];
            stackLen--;

            switch (formula[i]) {
                case '*': {
                     stackLen++;
                     options[stackLen] = (n * m);
                     break;
                }
                case '/': {
                     stackLen++;
                     options[stackLen] = (n / m);
                     break;
                }
                case '+': {
                     stackLen++;
                     options[stackLen] = (n + m);
                     break;
                }
                case '-': {
                     stackLen++;
                     options[stackLen] = (n - m);
                     break;
                }
            }
        }
    }

    printf("
結(jié)果為: %.2f
" , options[0]);
}

執(zhí)行結(jié)果

# ./a.out
3298+*3/35/*+

結(jié)果為: 9.80
#



審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7613

    瀏覽量

    137238
  • 計算器
    +關注

    關注

    16

    文章

    437

    瀏覽量

    37402

原文標題:利用棧實現(xiàn)計算器,實戰(zhàn)挺好

文章出處:【微信號:技術(shù)讓夢想更偉大,微信公眾號:技術(shù)讓夢想更偉大】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關推薦

    VirtualLab Fusion應用:相干時間和相干長度計算器

    摘要 在本用例中,我們介紹了一種計算器,它可以根據(jù)給定光源的波譜信息快速估計其時間相干特性。然后,可以將該計算器的結(jié)果自動復制到通用探測中,以便在考慮時間相干性時應用近似方法,而無需
    發(fā)表于 12-27 08:48

    LP光纖模式計算器

    :漸變折射率 (GRIN) 光纖 光纖模式計算器允許定義線性偏振貝塞爾模式和線性偏振拉蓋爾模式。 對于 GRIN 光纖,定義了梯度常數(shù)。 然后通過下式計算折射率 與前一種情況樣,
    發(fā)表于 12-18 13:36

    使用DRV421進行設計:系統(tǒng)參數(shù)計算器

    電子發(fā)燒友網(wǎng)站提供《使用DRV421進行設計:系統(tǒng)參數(shù)計算器.pdf》資料免費下載
    發(fā)表于 10-26 09:52 ?0次下載
    使用DRV421進行設計:系統(tǒng)參數(shù)<b class='flag-5'>計算器</b>

    一種利用CSD16327Q3實現(xiàn)企業(yè)固態(tài)硬盤鉭電容短路保護的方法

    電子發(fā)燒友網(wǎng)站提供《一種利用CSD16327Q3實現(xiàn)企業(yè)固態(tài)硬盤鉭電容短路保護的方法.pdf》資料免費下載
    發(fā)表于 10-25 10:22 ?0次下載
    <b class='flag-5'>一種</b><b class='flag-5'>利用</b>CSD16327Q3<b class='flag-5'>實現(xiàn)</b>企業(yè)固態(tài)硬盤鉭電容短路保護的方法

    一種簡單高效配置FPGA的方法

    本文描述了一種簡單高效配置FPGA的方法,該方法利用微處理從串行外圍接口(SPI)閃存配置FPGA設備。這種方法減少了硬件組件、板空間和成本。
    的頭像 發(fā)表于 10-24 14:57 ?727次閱讀
    <b class='flag-5'>一種</b><b class='flag-5'>簡單</b>高效配置FPGA的方法

    基于FPGA的計算器設計

    本文通過FPGA實現(xiàn)8位十進制數(shù)的加、減、乘、除運算,通過矩陣鍵盤輸入數(shù)據(jù)和運算符,矩陣鍵盤的布局圖如下所示。該計算器可以進行連續(xù)運算,當按下等號后,可以直接按數(shù)字進行下次運算,或者按運算符,把上次運算結(jié)果作為本次運算的第個操
    的頭像 發(fā)表于 10-24 14:28 ?671次閱讀
    基于FPGA的<b class='flag-5'>計算器</b>設計

    CAN位時序參數(shù)計算器

    電子發(fā)燒友網(wǎng)站提供《CAN位時序參數(shù)計算器.pdf》資料免費下載
    發(fā)表于 10-11 09:55 ?1次下載
    CAN位時序參數(shù)<b class='flag-5'>計算器</b>

    一種利用wireshark對遠程服務/路由網(wǎng)絡抓包方法

    一種利用wireshark對遠程服務/路由網(wǎng)絡抓包方法
    的頭像 發(fā)表于 09-21 08:03 ?3315次閱讀
    <b class='flag-5'>一種</b><b class='flag-5'>利用</b>wireshark對遠程服務<b class='flag-5'>器</b>/路由<b class='flag-5'>器</b>網(wǎng)絡抓包方法

    色環(huán)電阻計算器的研究與應用

    個理想的色環(huán)電阻計算器的界面應該包含個顏色選擇,讓用戶能夠通過點擊或下拉菜單選擇各個顏色環(huán)。而在程序邏輯層面,計算器需要具備實時反饋功
    的頭像 發(fā)表于 09-18 13:45 ?377次閱讀

    平平無奇計算器:520能對你說多少次?

    5月是個愛人愛己愛勞動的月份剛剛過去的5月20日小滿遇見520,人生小滿勝萬全情侶們說“愛意恰逢其時”計算器對小白說“520”……噠噠噠本期測評產(chǎn)品為:簡易計算器計算器對我說無數(shù)次
    的頭像 發(fā)表于 05-25 08:04 ?719次閱讀
    平平無奇<b class='flag-5'>計算器</b>:520能對你說多少次?

    HarmonyOS開發(fā)案例:【計算器

    基于基礎組件、容器組件,實現(xiàn)個支持加減乘除混合運算的計算器。
    的頭像 發(fā)表于 05-07 15:31 ?1423次閱讀
    HarmonyOS開發(fā)案例:【<b class='flag-5'>計算器</b>】

    蘋果將為iPad推出原生計算器應用

    早前,IT之家曾披露,此次蘋果還計劃對macOS系統(tǒng)內(nèi)的計算器應用進行功能升級,這是該軟件近10年來的首次重大設計變革。據(jù)悉,蘋果正在內(nèi)部測試款名為“GreyParrot”的全新計算器應用。
    的頭像 發(fā)表于 04-24 14:10 ?478次閱讀

    一種簡單的降壓式開關穩(wěn)壓LM2575數(shù)據(jù)表

    電子發(fā)燒友網(wǎng)站提供《一種簡單的降壓式開關穩(wěn)壓LM2575數(shù)據(jù)表.pdf》資料免費下載
    發(fā)表于 04-23 11:23 ?0次下載
    <b class='flag-5'>一種</b><b class='flag-5'>簡單</b>的降壓式開關穩(wěn)壓<b class='flag-5'>器</b>LM2575數(shù)據(jù)表

    OpenHarmony開發(fā)案例:【分布式計算器

    使用分布式能力實現(xiàn)簡單計算器應用,可以進行簡單的數(shù)值計算,支持遠程拉起另
    的頭像 發(fā)表于 04-11 15:24 ?1075次閱讀
    OpenHarmony開發(fā)案例:【分布式<b class='flag-5'>計算器</b>】

    AWTK 開源串口屏開發(fā)(13) - 計算器應用

    計算器個常見的應用程序,在AWTK串口屏中,利用fscript表達式計算函數(shù),無需編寫行傳統(tǒng)的代碼,即可
    的頭像 發(fā)表于 03-16 08:23 ?5570次閱讀
    AWTK 開源串口屏開發(fā)(13) - <b class='flag-5'>計算器</b>應用