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 "; 23 while(getline(cin,expr)){ 24 analyze(0,expr.size()-1,rootnode); 25 output(rootnode); 26 cout << " -----------------" << 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,先找到的运算符构造的节点必然有较低优先级的输出
将构造的树后序遍历得到逆波兰表达式: