题目大意
将一个含有+,-,^,()的表达式按照运算顺序转换成树状的形式。
解题分析
用递归的方式来处理表达式,首先直接去掉两边的括号(如果不止一对全部去光),然后找出不在括号内且优先级最低的符号。如果优先级相同,则如果是左结合性(+,-,*,/)则选择最右边的一个,如果是右结合性(^)则选择最最左边的一个。
主要恶心的地方在于输出上。主要是记录一下每个点和符号的位置,在递归和返回时传递一些参数。
ps:虽然输出比较恶心,但最终实现出来后还是感到十分地身心愉悦。
参考程序
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int,int> pii; 4 string s; 5 int a[100000]; 6 int level(char ch) 7 { 8 switch (ch) 9 { 10 case ‘+‘:; 11 case ‘-‘:return 1; 12 case ‘*‘:; 13 case ‘/‘:return 2; 14 case ‘^‘:return 3; 15 default:return 4; 16 } 17 } 18 19 int r,c,tmp=0; 20 21 struct node{ 22 int l,mid,r,len; 23 char ch; 24 }w[100000]; 25 26 pii solve(int x,int y,int heap,int op) 27 { 28 //cout<<s.substr(x,y-x+1)<<endl; 29 if (heap>r) r=heap; 30 if (op>c) c=op; 31 while (s[x]==‘(‘ && s[y]==‘)‘) 32 { 33 int t=0,flag=1; 34 for (int i=x+1;i<=y-1;i++) 35 { 36 if (s[i]==‘(‘) t++; else if (s[i]==‘)‘) t--; 37 if (t<0) flag=0; 38 } 39 if (flag) 40 { 41 x++; 42 y--; 43 } 44 else break; 45 } 46 int len=y-x+1; 47 if (len==1) 48 { 49 w[++tmp]=(node){op,op,op,heap,s[x]}; 50 return pii(1,1); 51 } 52 for (int i=x;i<=y;i++) a[i]=0; 53 if (s[x]==‘(‘) a[x]=1; else a[x]=0; 54 for (int i=x+1;i<=y;i++) 55 if (s[i]==‘(‘) a[i]=a[i-1]+1; else 56 if (s[i]==‘)‘) a[i]=a[i-1]-1; else 57 a[i]=a[i-1]; 58 int p=0,mx=5; 59 for (int i=x;i<=y;i++) 60 { 61 if (a[i]==0) 62 if (s[i]==‘^‘ && level(s[i])<mx || s[i]!=‘^‘ && level(s[i])<=mx ) 63 { 64 p=i; 65 mx=level(s[i]); 66 } 67 } 68 pii left=solve(x,p-1,heap+1,op); 69 int now=op+left.second+2; 70 pii right=solve(p+1,y,heap+1,now+3); 71 w[++tmp]=(node){op+left.first-1,op+left.second+2,now+right.first+3-1,heap,s[p]}; 72 return pii(left.second+3,left.second+5+right.second); 73 } 74 int cmp(const node &a,const node &b) 75 { 76 return a.len<b.len || a.len==b.len && a.mid<b.mid; 77 } 78 int main() 79 { 80 freopen("tree.in","r",stdin); 81 freopen("tree.out","w",stdout); 82 cin>>s; 83 pii p=solve(0,s.length()-1,1,1); 84 sort(w+1,w+tmp+1,cmp); 85 for (int h=1;h<=w[tmp].len;h++) 86 { 87 int i,j; 88 for (i=1;w[i].len!=h;i++); 89 for (j=i;w[j+1].len==h;j++); 90 if (h!=1) 91 { 92 for (int t=1;t<=w[i].mid-1;t++) printf(" "); 93 printf("|"); 94 for (int k=i+1;k<=j;k++) 95 { 96 for (int t=w[k-1].mid+1;t<=w[k].mid-1;t++) printf(" "); 97 printf("|"); 98 } 99 printf("\n"); 100 } 101 for (int t=1;t<=w[i].l-1;t++) printf(" "); 102 if (level(w[i].ch)!=4) printf("."); 103 for (int t=w[i].l+1;t<=w[i].mid-2;t++) printf("-"); 104 if (level(w[i].ch)!=4) printf("["); 105 printf("%c",w[i].ch); 106 if (level(w[i].ch)!=4) printf("]"); 107 for (int t=w[i].mid+2;t<=w[i].r-1;t++) printf("-"); 108 if (level(w[i].ch)!=4) printf("."); 109 for (int k=i+1;k<=j;k++) 110 { 111 for (int t=w[k-1].r+1;t<=w[k].l-1;t++) printf(" "); 112 if (level(w[k].ch)!=4) printf("."); 113 for (int t=w[k].l+1;t<=w[k].mid-2;t++) printf("-"); 114 if (level(w[k].ch)!=4) printf("["); 115 printf("%c",w[k].ch); 116 if (level(w[k].ch)!=4) printf("]"); 117 for (int t=w[k].mid+2;t<=w[k].r-1;t++) printf("-"); 118 if (level(w[k].ch)!=4) printf("."); 119 } 120 printf("\n"); 121 } 122 }
时间: 2024-10-09 21:43:12