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类型,然后分开设栈。

posted @ 2017-08-25 11:08  whalelife  阅读(7077)  评论(2编辑  收藏  举报