后缀表达式转换总结

  • Post author:
  • Post category:其他




中缀转后缀

1.维护一个符号栈

2.对于数字,直接加入结果ans

3.对于左括号,直到遇到右括号,把括号中间的数字全部添加到结果ans

4.大于栈顶元素则push,小于则pop。(大进小出)

5.弹出栈中其他符号

由于没有对数字相连进行处理,只能处理单个数组的情况

int pr(char o)//传入操作符,返回优先级
{
    int pri[10]={0,0,1,1,2,2,3};//priority
    char op[10]={'#','(','+','-','*','/','^'};
    for(int i=0;i<6;i++)
        if(op[i]==o)return pri[i];
}

string infix_to_postfix(string in)//中缀转后缀
{
    string ans="";
    stack<char>s;
    s.push('#');//作栈底使用
    for(int i=0;i<in.length();i++){//处理表达式
        if(in[i]>='0'&&in[i]<='9')ans+=in[i];//处理数字
        else if(in[i]=='(')s.push(in[i]);//处理括号
        else if(in[i]==')'){
            while(s.top()!='(')ans+=s.top(),s.pop();
            s.pop();//左括号
        }
        else{//处理操作符
            if(pr(in[i])>pr(s.top()))s.push(in[i]);
            else{
                while(pr(in[i])<=pr(s.top()))ans+=s.top(),s.pop();
                s.push(in[i]);
            }
        }
    }
    while(s.top()!='#')ans+=s.top(),s.pop();
    return ans;
}

测试样例:

8-(3+2*6)/5+4


输出结果:

8326*+5/-4+




后缀表达式求值

由于没有对数字相连进行处理,只能处理单个数组的情况

在这里插入图片描述

遇到符号,则把栈顶元素和次栈顶元素拿出去运算即可。由于进栈导致顺序倒置,所以是

运算规则 : 次栈顶元素 操作符 栈顶元素

int calc(int num_a,char o,int num_b)
{
    switch(o){
        case '+':return num_a+num_b;
        case '-':return num_a-num_b;
        case '*':return num_a*num_b;
        case '/':return num_a/num_b;
        case '^':return pow(num_a,numb_b);
    }
}

int calc_postfix(string in)
{
    stack<int>s;
    for(int i=0;i<in.length();i++){
        if(in[i]>='0'&&in[i]<='9')s.push(in[i]-'0');
        else {
            int b = s.top();s.pop();
            int a = s.top();s.pop();
            s.push(calc(a,in[i],b));
        }
    }
    return s.top();
}



单位数的中缀求值

把前面两个步骤合并起来

#include<bits/stdc++.h>
using namespace std;

string str;
int pr(char o)//传入操作符,返回优先级
{
    int pri[10]={0,1,1,2,2,3};//priority
    char op[10]={'#','+','-','*','/'};
    for(int i=0;i<6;i++)
        if(op[i]==o)return pri[i];
}

string infix_to_postfix(string in)//中缀转后缀
{
    string ans="";
    stack<char>s;
    s.push('#');//作栈底使用
    for(int i=0;i<in.length();i++){//处理表达式
        if(in[i]>='0'&&in[i]<='9')ans+=in[i];//处理数字
        else if(in[i]=='(')s.push(in[i]);//处理括号
        else if(in[i]==')'){
            while(s.top()!='(')ans+=s.top(),s.pop();
            s.pop();//左括号
        }
        else{//处理操作符
            if(pr(in[i])>pr(s.top()))s.push(in[i]);
            else{
                while(pr(in[i])<=pr(s.top()))ans+=s.top(),s.pop();
                s.push(in[i]);
            }
        }
    }
    while(s.top()!='#')ans+=s.top(),s.pop();
    return ans;
}

int calc(int num_a,char o,int num_b)
{
    switch(o){
        case '+':return num_a+num_b;
        case '-':return num_a-num_b;
        case '*':return num_a*num_b;
        case '/':return num_a/num_b;
    }
}

int calc_postfix(string in)
{
    stack<int>s;
    for(int i=0;i<in.length();i++){
        if(in[i]>='0'&&in[i]<='9')s.push(in[i]-'0');
        else {
            int b = s.top();s.pop();
            int a = s.top();s.pop();
            s.push(calc(a,in[i],b));
        }
    }
    return s.top();
}

int main()
{
    cin>>str;
    cout<<calc_postfix(infix_to_postfix(str))<<endl;
    return 0;
}



表达式中多位数处理

思路:对读入的中缀表达式进行预处理,将数字分开。计算时以@作为分割符来读取数。

#include<bits/stdc++.h>
using namespace std;

string str;
int pr(char o)//传入操作符,返回优先级
{
    int pri[10]={0,0,1,1,2,2,3};//priority
    char op[10]={'#','(','+','-','*','/','^'};
    for(int i=0;i<6;i++)
        if(op[i]==o)return pri[i];
}

int is_op(char o)//判断是否为符号
{
    if(o>='0'&&o<='9')return 0;
    return 1;
}

string exp_deal(string in)//对表达式进行处理,防止数字相连,这里以@分隔
{
    string deal="";
    for(int i=0;i<in.length();i++){
        deal+=in[i];
        if(in[i]>='0'&&in[i]<='9'&&is_op(in[i+1]))deal+='@';
    }
    return deal;
}

string infix_to_postfix(string in)//中缀转后缀
{
    in=exp_deal(in);//对多位数字进行处理
    string ans="";
    stack<char>s;
    s.push('#');//作栈底使用
    for(int i=0;i<in.length();i++){//处理表达式
        if(in[i]>='0'&&in[i]<='9'||in[i]=='@')ans+=in[i];//处理数字
        else if(in[i]=='(')s.push(in[i]);//处理括号
        else if(in[i]==')'){
            while(s.top()!='(')ans+=s.top(),s.pop();
            s.pop();//左括号
        }
        else{//处理操作符
            if(pr(in[i])>pr(s.top()))s.push(in[i]);
            else{
                while(pr(in[i])<=pr(s.top()))ans+=s.top(),s.pop();
                s.push(in[i]);
            }
        }
    }
    while(s.top()!='#')ans+=s.top(),s.pop();
    return ans;
}

int calc(int num_a,char o,int num_b)
{
    switch(o){
        case '+':return num_a+num_b;
        case '-':return num_a-num_b;
        case '*':return num_a*num_b;
        case '/':return num_a/num_b;
        case '^':return (int)pow(num_a,num_b);
    }
}

int calc_postfix(string in)
{
    stack<int>s;
    int num=0;
    for(int i=0;i<in.length();i++){
        if(in[i]>='0'&&in[i]<='9')
            num = num*10+(in[i]-'0');
        else if(in[i]=='@')
            s.push(num),num=0;
        else {
            int b = s.top();s.pop();
            int a = s.top();s.pop();
            s.push(calc(a,in[i],b));
        }
    }
    return s.top();
}


int main()
{
    cin>>str;
    cout<<calc_postfix(infix_to_postfix(str))<<endl;
    return 0;
}



版权声明:本文为weixin_43615816原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。