表達式求值-中綴表達式轉爲後綴表達式

簡單計算只包含()和+-*/的表達式

思路:先將中綴表達式轉化爲後綴表達式,然後計算後綴表達式的值。

規則:時刻保證棧內 上面的元素 比 下邊的元素 優先級高
步驟:
1.如果當前元素 比 棧頂元素 優先級 高,那麼把當前元素壓入棧內能保證規則成立,所以直接壓棧。
2.如果當前元素 比 棧頂元素 優先級 低,那麼把棧頂元素彈出放到後綴表達式裏。
3.重複第二步,直到 當前元素 比 棧頂元素 優先級 高,則當前元素壓入棧內能保證規則成立,所以直接壓棧。

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

int main(){
    string s;///存原表達式
    stack <char> res;///將原表達式轉化爲後綴表達式所用到的符號棧
    cin>>s;
    string behind[100];///存後綴表達式的字符串數組

    int cnt = 0;///後綴表達式中字符串的個數(下標)

    ///把前綴表達式轉化爲後綴表達式
    for(int i = 0;i<s.length();){
        if(s[i]>='0' && s[i]<='9'){///以數字打頭的一定是數字
            char temp[10];///暫時放這個數
            int t1 = 0;///這個數變成字符串時的長度(下標)
            while(s[i]>='0' && s[i]<='9'){///如果有小數可以加上s[i]=='.'
               temp[t1] = s[i];
               i++;
               t1++;
            }
            temp[t1]=0;///結束符,標誌字符串已經結束
            ///數已經處理好了,直接存放到後綴表達式裏
            behind[cnt] = temp;
            cnt++;
        }

        else{///如果是符號

            if(s[i] == '('){///左括號直接壓棧
                res.push(s[i]);
            }
            else if(s[i] == ')'){///把左括號後的符號依次彈出,寫入後綴表達式中
                while(!res.empty() && res.top() != '('){
                    string temp = " ";///聲明一個string類型變量,內存空間是一個字符大小
                    temp[0] = res.top();
                    behind[cnt] = temp;
                    cnt++;
                    res.pop();
                }
                res.pop();///彈出(但是不寫進後綴表達式
            }

            else if(s[i] == '+' || s[i] == '-'){///把 + - * / 彈出並寫入後綴表達式
                while(!res.empty() && res.top() != '('){
                    string temp = " ";

                    temp[0] = res.top();
                    behind[cnt] = temp;
                    cnt++;
                    res.pop();
                }
                res.push(s[i]);
            }
            else{///把* / 彈出並寫入後綴表達式
                while(!res.empty()&&(res.top()=='*'||res.top()=='/')){
                    string temp = " ";
                    temp[0] = res.top();
                    behind[cnt] = temp;
                    cnt++;
                    res.pop();
                }
                res.push(s[i]);
            }

            i++;
        }
    }

    while(!res.empty()){///把棧內剩餘符號依次放入後綴表達式中
        string temp = " ";
        temp[0] = res.top();
        behind[cnt] = temp;
        cnt++;
        res.pop();
    }
    cout<<"後綴表達式:"<<endl;
    for(int i = 0;i<cnt;++i){
        cout<<behind[i]<<" ";
    }

    ///計算後綴表達式的值
    stack<double> q;///計算表達式值的棧
    bool error = 0;///表達式合法性判斷
    for(int i = 0; i<cnt; i++){
        ///如果是符號
        if((behind[i][0]== '+' || behind[i][0]=='-' || behind[i][0]=='*' || behind[i][0]=='/')){
            if(q.size()<2) {error = 1; break;}
            double aa = q.top(); q.pop();
            double bb = q.top(); q.pop();
            if(behind[i][0]== '+') q.push(aa+bb);
            else if(behind[i][0]== '-') q.push(bb-aa);///這裏注意順序,棧頂元素是減數
            else if(behind[i][0]== '*') q.push((aa*bb));
            else if(behind[i][0]== '/') {
                if(bb==0){error = 1; cout<<"除0 ";break;}///排除除零錯誤
                q.push(bb/aa);///注意順序
            }
        }
        else{
            /// c_str() 函數是string中轉化爲字符數組的函數
            ///atof() 是c語言中將字符數組轉化爲浮點型數據函數
            double x = atof(behind[i].c_str());
            q.push(x);
        }
    }

    if(q.size() != 1) error = 1;

    if(error) cout<<"ERROR";
    else cout<<endl<<"結果是:"<<q.top();

    return 0;
}


發佈了229 篇原創文章 · 獲贊 252 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章