构造树求解逆波兰表达式

 

  1 #include<iostream>
  2 #include<string>
  3 #include<vector>
  4 #include<tuple>
  5 
  6 using namespace std;
  7 
  8 class Node{
  9 public :
 10     char val;
 11     Node *lch,*rch;
 12     Node():val(0),lch(nullptr),rch(nullptr){}
 13     Node(char tv,Node *tl,Node *tr):val(tv),lch(tl),rch(tr){}
 14 };
 15 
 16 //Reverse Polish notation,RPN
 17 class Rpn{
 18 public :
 19     string expr;
 20     Node *rootnode;
 21     void solve(){
 22         cout << "input expression\n";
 23         while(getline(cin,expr)){
 24             analyze(0,expr.size()-1,rootnode);
 25             output(rootnode);
 26             cout << "\n-----------------" << endl;
 27         }
 28     }
 29     void analyze(int left,int right,Node *&knode){
 30         if(left>right)return;
 31         tuple<int,int> tup = truncparentheses(left,right);
 32         left = get<0>(tup);
 33         right = get<1>(tup);
 34         int bracnt = 0;
 35         bool opflag1 = false; //plus or sub
 36         bool opflag2 = false; //mult or div
 37         int muldivpos = 0;
 38         int i = 0;
 39         for(i=right;i>=left;--i){
 40             if(expr[i]=='(')bracnt++;
 41             if(expr[i]==')')bracnt--;
 42             if(!bracnt){
 43                 if(expr[i]=='+'||expr[i]=='-'){
 44                     opflag1 = true;
 45                     break;
 46                 }
 47                 if(expr[i]=='*'||expr[i]=='/'){
 48                     muldivpos = (opflag2) ? muldivpos : i;
 49                     opflag2 = true;
 50                 }
 51             }
 52         }
 53         if(opflag1){
 54             knode = new Node(expr[i],nullptr,nullptr);
 55             analyze(left,i-1,knode->lch);
 56             analyze(i+1,right,knode->rch);
 57         }
 58         else if(opflag2){
 59             knode = new Node(expr[muldivpos],nullptr,nullptr);
 60             analyze(left,muldivpos-1,knode->lch);
 61             analyze(muldivpos+1,right,knode->rch);
 62         }
 63         else{
 64             knode = new Node(expr[left],nullptr,nullptr);
 65         }
 66     }
 67     void output(Node *knode){
 68         if(!knode)return;
 69         if(knode->lch){
 70             output(knode->lch);
 71         }
 72         if(knode->rch){
 73             output(knode->rch);
 74         }
 75         cout << knode->val;
 76     }
 77     tuple<int,int> truncparentheses(int left,int right){
 78         bool flag = false;
 79         int bracnt = 0;
 80         //cout << "in trunc : " << left << "~" << right << endl;
 81         while(1){
 82             bracnt = 0;
 83             for(int i=left;i<=right;++i){
 84                 //cout << i << ":" << expr[i] << endl;
 85                 if(expr[i]=='(')bracnt++;
 86                 else if(expr[i]==')')bracnt--;
 87                 //cout <<"bracnt : " << bracnt << endl;
 88                 else if(bracnt==0){
 89                     flag = true;
 90                     break;
 91                 }
 92             }
 93             if(flag){
 94                 break;
 95             }
 96             else{
 97                 ++left;
 98                 --right;
 99             }
100         }
101         //cout << "after trunc : " << left << "~" << right << endl;
102         tuple<int,int> tup = make_tuple(left,right);
103         return tup;
104     }
105 };
106 int main()
107 {
108     Rpn myrpn;
109     myrpn.solve();
110     return 0;
111 }

注意,由于中缀式的运算规则是从左到右,所以遍历left~right时从right遍历到left,先找到的运算符构造的节点必然有较低优先级的输出

 

 将构造的树后序遍历得到逆波兰表达式:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值