中缀表达式转后缀表达式(二叉树实现)

前言

最近在系统复习刷题单,做到了本应滚瓜烂熟的表达式转换的题,忘记了出栈入栈的规则,调了很久也没有过。
最后怒写了一棵表达式树过了,个人认为这个方法便于记忆,也比较好写。

代码

核心流程就是在区间中寻找最后一个运算的运算符,然后将这个运算符作为根,递归左右区间进行建树,叶子节点全部为操作数。
如果区间内不存在运算符,就一定只有一个数字,读入数字作为叶子节点。
代码:以洛谷P1175为例

#include <bits/stdc++.h>
using namespace std;
string s1;
int pr;
int len;
int cnt;
struct node{
    int now;
    int lson;
    int rson;
    int flag;
    int val;
    char ch;
}node[100005];
int build(int l,int r){
    cnt++;
    int now1=cnt;
    node[cnt].now=cnt;
    int min1=1000;
    int min2=0;
    int pr=0;
    for(int i=l;i<=r;i++){  //寻找最后一个运算的运算符
        if(s1[i]=='-'||s1[i]=='+'){
            if(pr<=min1){
                min1=pr;
                min2=i;
            }
        }
        else if(s1[i]=='*'||s1[i]=='/'){
            if(pr+1<=min1){
                min1=pr+1;
                min2=i;
            }
        }
        else if(s1[i]=='^'){
            if(pr+2<=min1){
                min1=pr+2;
                min2=i;
            }
        }
        else if(s1[i]=='('){
            pr+=3;
        }
        else if(s1[i]==')'){
            pr-=3;
        }
    }
    if(min1==1000){ //否则读入数据
        int sz=0;
        for(int i=l;i<=r;i++){
            if(s1[i]<='9'&&s1[i]>='0'){
                sz*=10;
                sz+=s1[i]-'0';
            }
        }
        node[now1].val=sz;
        node[now1].flag=0;
    }
    else{
        node[now1].lson=build(l,min2-1);
        node[now1].rson=build(min2+1,r);
        node[now1].flag=1;
        node[now1].ch=s1[min2];
    }
    return now1;
}
void tran(int now){     //后序遍历转化为后缀表达式
    if(now==0)return;
    tran(node[now].lson);
    tran(node[now].rson);
    if(node[now].flag==1){
        cout<<node[now].ch<<' ';
    }
    else{
        cout<<node[now].val<<' ';
    }
    return;
}
int cnt1;
int flag1;
deque<pair<int,int> > q1;       //依次输出每一步运算结果要用到
void tran1(int now){
    if(now==0)return;
    tran1(node[now].lson);
    tran1(node[now].rson);
    if(node[now].flag==1){
        if(flag1==0){
            node[now].flag=0;
            if(node[now].ch=='+'){
                node[now].val=node[node[now].lson].val+node[node[now].rson].val;
            }
            else if(node[now].ch=='-'){
                node[now].val=node[node[now].lson].val-node[node[now].rson].val;
            }
            else if(node[now].ch=='*'){
                node[now].val=node[node[now].lson].val*node[node[now].rson].val;
            }
            else if(node[now].ch=='/'){
                node[now].val=node[node[now].lson].val/node[node[now].rson].val;
            }
            else if(node[now].ch=='^'){
                node[now].val=(int)pow(node[node[now].lson].val,node[node[now].rson].val);
            }
            node[now].lson=node[now].rson=0;
            q1.pop_back();
            q1.pop_back();
            q1.push_back(make_pair(0,node[now].val));
            flag1=1;
        }
        else{
            q1.push_back(make_pair(1,node[now].ch));
        }
    }
    else{
        q1.push_back(make_pair(0,node[now].val));
    }
    return;
}
int main(){
    cin>>s1;
    len=s1.length();
    for(int i=0;i<len;i++){
        if(s1[i]=='-'||s1[i]=='+'||s1[i]=='*'||s1[i]=='/'||s1[i]=='^')cnt1++;
    }
    int root=build(0,len-1);
    tran(root);
    cout<<endl;
    for(int i=1;i<=cnt1;i++){
        flag1=0;
        tran1(root);
        while(!q1.empty()){
            int temp=q1.front().first;
            if(temp==0){
                cout<<q1.front().second<<' ';
            }
            else{
                cout<<(char)q1.front().second<<' ';
            }
            q1.pop_front();
        }
        cout<<endl;
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值