题意:在不改变表达式的含义的情况下去除多余的括号,输入保证表达式是正确的。
WA了整整一天,挺有意思的一题。
给两组数据,我是主要就错在这两个地方了:
2
A-((A+A))
A-(A+(A))
结果都是A-(A+A)
思路(优先级从上往下,一开始没考虑优先级的问题):
1.开头的括号可去除
2.括号内没有运算符的括号可去除
3.括号前不是减号的括号可去除
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN = 350; 5 6 struct node 7 { 8 char oper; 9 int addr; 10 bool have; 11 }; 12 13 char str[MAXN]; 14 char ans[MAXN]; 15 bool vis[MAXN]; 16 node stack[MAXN]; 17 18 int main() 19 { 20 int T; 21 scanf( "%d", &T ); 22 getchar(); 23 while ( T-- ) 24 { 25 gets( str ); 26 int top = 0; 27 memset( vis, true, sizeof(vis) ); 28 for( int i = 0; str[i]; ++i ) 29 { 30 if ( str[i] == '(' ) 31 { 32 stack[++top].addr = i; 33 stack[top].have = false; 34 int a = i - 1; 35 while ( a >= 0 && str[a] == ' ' ) --a; 36 if ( a >= 0 ) stack[top].oper = str[a]; 37 else stack[top].oper = '@'; 38 } 39 else if ( str[i] == ' ' ) 40 { 41 vis[i] = false; 42 } 43 else if ( str[i] == '+' || str[i] == '-' ) 44 { 45 stack[top].have = true; 46 } 47 else if ( str[i] == ')' ) 48 { 49 if ( (!stack[top].have) || stack[top].oper != '-' )//一开始这两个条件写反了,应该先判断括号内有没有运算符,再判断括号前是否是减号 50 { 51 vis[ stack[top].addr ] = false; 52 vis[i] = false; 53 int a = stack[top].addr - 1; //如果内层括号可以消去,不能直接把内层括号中包含运算符的情况赋值给外层括号 54 while ( str[a] == ' ' ) --a; //应当先查找此括号前是否还包含运算符 55 if ( str[a] == '(' ) stack[top - 1].have = stack[top].have;// 不过我觉得我WA的地方有点奇葩,一般人应该不会犯这种错吧 56 } 57 --top; 58 } 59 } 60 61 for ( int i = 0; str[i]; ++i ) 62 if ( vis[i] ) putchar(str[i]); 63 puts(""); 64 65 } 66 return 0; 67 }