c++用棧實現算術表達式的計算


用棧將算術表達式轉換成后綴表達式的形式大家應該不陌生了,但是我在實現計算的時候卻發現坑還是不少。

題目描述: 讀入一個只包含 +, -, *, / 的非負整數計算表達式,計算該表達式的值。

輸入描述: 測試輸入包含若干測試用例,每個測試用例占一行,每行不超過200個字符,整數和運算符之間用一個空格分隔。沒有非法表達式。當一行中只有0時輸入結束,相應的結果不要輸出。

輸出描述: 對每個測試用例輸出1行,即該表達式的值,精確到小數點后2位。

示例1
輸入

1 + 2
4 + 2 * 5 - 7 / 11
0

輸出

3.00
13.36

PS:不知道為什么,$轉義總是失敗,有朋友知道怎么轉義的話請留言告訴我~
​做這題必須注意幾個問題:

* 當棧里沒有運算符的時候,直接對棧頂和字符串讀取到的運算符進行比較會出錯,因此這里在一開始就往棧里壓入了一個我們設計的符號'#'
* 當我們遍歷字符串的時候,遇到數字要格外注意,因為此時一切都是字符形式了,比如說輸入11就會變成兩個字符1,因此我們在讀取的時候要進行判斷,確保所有連在一起的數字字符都讀到了,而不是只讀到了第一個字符。
* 當我們遍歷完字符串的時候,很有可能棧里還留有沒處理的運算符,因此我們需要繼續處理棧里的操作符,這里在字符串后面加入了符號//$是很巧妙的,\$的優先級比'#'高,比其他符號低,因此這保證了當讀到字符\$時,它一定比棧頂出現的所有字符優先級高(除了它自己和'#'),這樣就可以讓棧里剩下的運算符一個一個彈出來,至到處理結束,棧頂為'\#',壓入\$。

具體代碼如下:

#include<iostream>
#include<stack>
#include<string>
#include<stdio.h>
#include<cctype>
using namespace std;


/**
 * 比較操作符優先級的函數

 */
int OperPrecedence(char a){
    if(a == '/' || a == '*'){
        return 3;
    }else if(a == '+' || a == '-' ){
        return 2;
    }else if(a == '$'){
        return 1;
    }else if(a == '#'){
        return 0;
    }

}

/**
 * 實現運算
 */

double operNums(char oper, double num1, double num2){
    if(oper == '+'){
        return num1 + num2;
    }else if(oper == '-'){
        return num1 - num2;
    }else if(oper == '*'){
        return num1 * num2;
    }else if(oper == '/'){
        return num1 / num2;
    }
}

/**
 * 實現遇到數字往后移動直到數字確定
 */

int getNum(string str, int &index){
    string num = "";
    while(isdigit(str[index])){
        num += str[index];
        index ++;
    }

    return atoi(num.c_str());
}
int main(){
    stack<char> operStack;
    stack<double> numStack;
    string str;
    char oper;
    double num1;
    double num2;
    double sum = 0;
    int index = 0, preceResult;
    operStack.push('#');
    while (getline(cin, str))
    {

        str += '$';
        if(str[0] == '0'){
           
            break;
        }

        while(index < str.size()){
          
        if(str[index] == ' '){
            index++;
        }
        else if(isdigit(str[index])){
            //數字
            numStack.push(getNum(str, index));
        }else
        {
            //操作符
            //比較優先級

            if(OperPrecedence(operStack.top()) < OperPrecedence(str[index])){
                operStack.push(str[index]);
                index++;
            }else{
                num2 = numStack.top();
                numStack.pop();
                num1 = numStack.top();
                numStack.pop();
                oper = operStack.top();
                operStack.pop();
                numStack.push(operNums(oper, num1 ,num2));

            }
            
        }
        
        
        }
        // std::cout << "sum="<<sum << endl;
        printf("%.2f\n", numStack.top());
        index = 0;
        
        
    }
  


}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM