C++ 中綴轉后綴表達式並求值


//中綴轉后綴
#include<iostream>
#include<stack>
using namespace std;

int prio(char x){
    if(x=='*'||x=='/')  return 2;
    if(x=='+'||x=='-')  return 1;
    if(x=='(')  return 0;
    else return -1;
    
}
void in_to_post(char* inorder,char* &post){
    stack<char>S;
    int k=0;
    while(*inorder){
        //數字
        if(*inorder>='0'&&*inorder<='9'){
            post[k++] = *inorder;
        }
        //操作符
        else{
            if(S.empty())  {
                S.push(*inorder);
            }
            else if(*inorder=='('){
                S.push(*inorder);
            }
            else if(*inorder==')'){
                while(S.top()!='('){
                    post[k++]=S.top();
                    S.pop();
                }
                S.pop();
            }
            else{
                while(prio(*inorder)<=prio(S.top())){
                        post[k++]=S.top();
                        S.pop();
                    if(S.empty())   break;
                }
                S.push(*inorder);
            }
        }
        inorder++;
    }
    if(!S.empty()){
        char c =S.top();
        post[k++] = c;
        S.pop();
    }
}
//后綴表達式求值
int cal(int a,int b,char c){
    if(c=='+')  return a+b;
    else if(c=='-')  return a-b;
    else if(c=='*')  return a*b;
    else if(c=='/')  return a/b;
    else return 0;
}

int postcal(char* post){
    stack <int > s;
    while(*post){
        if(*post >='0'&& *post<='9'){
            s.push(*post);
        }
        else{
            int a = s.top()-48;
            s.pop();
            int b = s.top()-48;
            s.pop();
            int c = cal(b,a,*post);
            s.push(c+48);
        }
        post++;
    }
    return s.top()-48;
}

int main(){
    cout<<"輸入中綴表達式:"<<endl;
    char* inorder =new char;
    cin>>inorder;
    char* post= new char;
    cout<<"后綴表達式為:";
    in_to_post(inorder,post);
    cout<<post<<endl;
    int res = postcal(post);
    cout<<"后綴表達式計算結果:"<<res<<endl;
}

 

求解思想:

中綴轉后綴表達式:

  從左到右掃描輸入的中綴表達式,若是數字,則直接輸出到結果,若是運算符則判斷:

  1. ‘(’ :直接入棧;

  2. ‘)’:依次把棧中的運算符輸出到結果,知道出現‘(’,將左括號從棧中刪除;

  3. 若是其他運算符,判斷當前運算符與棧頂元素的優先級(*/ 為2,+-為1,( 為0,其他為-1),若是當前運算符優先級較高,則直接入棧,否則,依次輸入比當前運算符優先級高或相等的運算符,知道遇到不符合條件的元素或者遇到左括號為止,再將當前運算符入棧。

  掃描結束后,將棧內存放的運算符依次輸出到結果。

例如:3*5+((1+3)/2+1)

3 放入結果;          結果:3  棧內:

* 放入棧內;          結果:3  棧內:*

5 放入結果;            結果:35  棧內:*

+:將*輸入,+放入棧內     結果:35*  棧內:+

( 放入棧內;          結果:35*  棧內:+(

( 放入棧內;          結果:35*  棧內:+((

1 放入結果;          結果:35*1  棧內:+((

+ 放入棧內;            結果:35*1  棧內:+((+

3 放入結果;          結果:35*13  棧內:+((+

):輸出+,刪除(;       結果:35*13+  棧內:+(

/ 放入棧內;           結果:35*13+  棧內:+(/

2 放入結果;          結果:35*13+2  棧內:+(/

+: 輸出/,+放入棧內;     結果:35*13+2/  棧內:+(+

1 放入結果;           結果:35*13+2/1  棧內:+(+

):輸出+,刪除(;       結果:35*13+2/1+  棧內:+

把棧內剩余元素依次輸出;      結果:35*13+2/1++  棧內:

后綴表達式求值:

  從左到右掃描輸入的后綴表達式,若是數字則入棧;若是操作符,則從棧中取出兩個數,進行相應計算后,將結果放回棧中,;掃描完后,棧頂剩余元素就是結果。

由於輸入時並未區分數字和操作符,而是統一規定成了char 類型,所以要將每兩個操作數計算的結果也要轉換成ASCII碼對應的字符類型,所以要進行+-48的操作。

也可以在一開始讀取輸入的時候就區分int類型和char類型,然后分開設棧。


免責聲明!

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



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