91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

3天內不再提示

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

工程師鄧生 ? 來源:博客園 ? 作者:pdudos ? 2022-09-19 10:32 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

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

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

2. 關于數(shù)據(jù)結構: 棧

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

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

3. 中綴表達式 如何利用棧 轉換為后綴表達式

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

遍歷中綴表達式

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

判斷為(入棧

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

判斷為 * 或/

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

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

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

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

判斷為+-,則

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

實際例子

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

開始式子: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/*+

完畢

轉換代碼 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í)行結果

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

4. 利用棧 后綴表達式計算結果

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

假設后綴表達式是有效的

遍歷后綴表達式

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

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

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

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

實際例子

通過棧,將計算后綴表達式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í)行結果(n + m)入棧

:3 2 17

開始處理: *

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

:3 34

開始處理: 3

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

:3 34 3

開始處理: /

執(zhí)行規(guī)則2: 取出2個元素,m:3 n:34, 并且執(zhí)行結果(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í)行結果(n / m)入棧

:3 11.3 0.6

開始處理: *

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

:3 6.8

開始處理: +

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

:9.8

計算結果:9.8

完成

用C實現(xià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("
結果為: %.2f
" , options[0]);
}

執(zhí)行結果

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

結果為: 9.80
#



審核編輯:劉清

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

    關注

    183

    文章

    7645

    瀏覽量

    145827
  • 計算器
    +關注

    關注

    16

    文章

    441

    瀏覽量

    38936

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

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    STPMC1可編程多相電能計算器IC:設計與應用詳解

    STPMC1可編程多相電能計算器IC:設計與應用詳解 在電力計量領域,精準且高效的電能計算是關鍵。STPMC1作為款可編程多相電能計算器IC,為電力線系統(tǒng)的有效電能測量提供了強大的解
    的頭像 發(fā)表于 03-02 16:55 ?521次閱讀

    使用TFTP實現(xiàn)IAP的方法

    使用 TFTP 實現(xiàn) IAP 的方法廣泛應用于需要具有固件升級功能的嵌入式應用中(例如,嵌入式 Linux bootloader 中)。TFTP 是一種在 UDP 傳輸層上執(zhí)行的簡單文件傳輸協(xié)議。此
    發(fā)表于 12-10 07:21

    用PLC實現(xiàn)卷徑計算的兩算法

    卷徑計算,是動態(tài)計算如鋼卷,紙卷等存料量的一種方法,它是實現(xiàn)張力控制和自動充放料、以及甩尾控制的重要前提。卷徑計算目前主流的方法有兩
    的頭像 發(fā)表于 11-14 16:54 ?2204次閱讀
    用PLC<b class='flag-5'>實現(xiàn)</b>卷徑<b class='flag-5'>計算</b>的兩<b class='flag-5'>種</b>算法

    如何利用Trace機制實現(xiàn)LLCP預覽功能

    在藍牙協(xié)議開發(fā)過程中,有時需要預先知道 LLCP。本文將介紹如何利用 Trace 機制實現(xiàn) LLCP 預覽功能。
    的頭像 發(fā)表于 10-09 17:55 ?1982次閱讀

    Quartz Frequency 實戰(zhàn):熱力圖+計算器(6 篇)

    AT-cut 面向對象:嵌入式/硬件/射頻/物聯(lián)網(wǎng)工程師 內容亮點:可視化圖示 + 在線計算器 + 設計邊界與案例 大家好!整理了套石英定時(Quartz Timing)高原創(chuàng)度文章與工具
    發(fā)表于 10-09 15:42

    一種適用于超低噪聲應用的數(shù)字線性穩(wěn)壓

    線性穩(wěn)壓一種簡單的電壓轉換,可將較高的輸入電壓轉換為較低的輸出電壓。其行為特性就像個動態(tài)電阻
    的頭像 發(fā)表于 08-19 09:20 ?1571次閱讀

    一種新的無刷直流電機反電動勢檢測方法

    無位置傳感無刷直流電機的控制算法是近年來研究的熱點之,有霍爾位置信號直流電機根據(jù)霍爾狀態(tài)來確定通斷功率器件。利用無刷直流電機的數(shù)學模型,根據(jù)反電動勢檢測原理,提出了一種新的線反電動
    發(fā)表于 08-07 14:29

    Qorvo全新設計計算器:晶振選型、能耗預算計算器和鏈路預算與覆蓋范圍計算器

    款功能強大的PC端計算工具 。這些工具—— 晶振采購工具 、 能耗預算計算器 和 鏈路預算與覆蓋范圍計算器 ——讓優(yōu)化晶振選型、預測電池續(xù)航時間以及評估RF鏈路性能變得前所未有地簡單
    的頭像 發(fā)表于 06-24 17:51 ?1739次閱讀
    Qorvo全新設計<b class='flag-5'>計算器</b>:晶振選型、能耗預算<b class='flag-5'>計算器</b>和鏈路預算與覆蓋范圍<b class='flag-5'>計算器</b>

    VirtualLab:衍射角計算器

    可以通過“開始”選項卡下的“計算器”下拉列表訪問“衍射角計算器”。 設置輸入?yún)?shù) 用戶需要輸入光柵周期、入射角、波長的值,并定義光柵前后的材料。入射波和反射級次位于第一種材料中,而透射級次于第二
    發(fā)表于 06-16 08:48

    一種新型激光雷達慣性視覺里程計系統(tǒng)介紹

    針對具有挑戰(zhàn)性的光照條件和惡劣環(huán)境,本文提出了LIR-LIVO,這是一種輕量級且穩(wěn)健的激光雷達-慣性-視覺里程計系統(tǒng)。通過采用諸如利用深度與激光雷達點云關聯(lián)實現(xiàn)特征的均勻深度分布等先進技術,以及
    的頭像 發(fā)表于 04-28 11:18 ?1146次閱讀
    <b class='flag-5'>一種</b>新型激光雷達慣性視覺里程計系統(tǒng)介紹

    藍牙架構實現(xiàn)方案(藍牙協(xié)議方案)

    藍牙架構實現(xiàn)方案有哪幾種?我們般把整個藍牙實現(xiàn)方案叫做藍牙協(xié)議,因此這個問題也可以這么闡述:藍牙協(xié)議有哪些具體的架構方案?在藍牙協(xié)議
    的頭像 發(fā)表于 04-08 15:35 ?1623次閱讀
    三<b class='flag-5'>種</b>藍牙架構<b class='flag-5'>實現(xiàn)</b>方案(藍牙協(xié)議<b class='flag-5'>棧</b>方案)

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

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

    VirtualLab:衍射角計算器

    可以通過“開始”選項卡下的“計算器”下拉列表訪問“衍射角計算器”。 設置輸入?yún)?shù) 用戶需要輸入光柵周期、入射角、波長的值,并定義光柵前后的材料。入射波和反射級次位于第一種材料中,而透射級次于第二
    發(fā)表于 04-08 08:46

    一種分段氣隙的CLLC變換平面變壓設計

    ,驗證理論設計的正確性,為變壓制作提供理論依據(jù)。文中基于圖1電路拓撲研究了平面變壓的設計與實現(xiàn)方法。 2 一種分段氣隙的CLLC平面變壓
    發(fā)表于 03-27 13:57

    Made with KiCad(121):OpenRPNCalc 開源科學 RPN 計算器

    “? OpenRPNCalc 是款基于 STM32 微控制的科學計算器。 ” Made with KiCad 系列將支持新的展示方式。直接將以下鏈接復制到瀏覽中(或點擊“閱讀原文
    的頭像 發(fā)表于 03-26 11:45 ?1600次閱讀
    Made with KiCad(121):OpenRPNCalc 開源科學 RPN <b class='flag-5'>計算器</b>