明天软考,但是今天还是手痒,在soj又切了道水题1663,看cauchy做了,故也来切掉。

题目意思是一串合法的表达式字符串,仅包括大写字母,+,-,(,),空格,tab字符,把多余的括号去掉。如:(A+(B+C)+(D-E)) ->A+B+C+D-E

或者((B))->B

思路:

1.堆栈操作字符串括号屁屁额

2. pos[top] = index ;//记录括号的位置

pre[top++] = ch ; //记录括号前的那个字符

        num[i]//记录前i个字符有多少个大写字母。

        vis[i]//标记第i个字符是否可以消掉

3.当且仅当pre[top-1]是+或者(时或者()之间字母数量<=1的时候该括号对要消掉。

代码如下:

 

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

 

const int maxn = 1024 ;

char token , str[maxn] , ans[maxn] , pre[maxn] ;

int top , pos[maxn] , num[maxn] ;

bool vis[maxn] ;

 

void push(int index,char ch)

{

pos[top] = index ;

pre[top++] = ch ;

}

 

void pop()

{

top--;

}

 

inline void solve()

{

int i , k ;

char ch = '+' ;

memset(vis,0,sizeof(vis));

for ( i = 1 , top = num[0] = 0 ; str[i] ; i++)

{

num[i] = num[i-1] ;

if( str[i] == ' ' || str[i] == '\t' ) vis[i] = true ;

else if( str[i] == '(' )

{

push(i,ch);

ch = str[i] ;

}

else if( str[i] == ')' )

{

if( pre[top-1] == '(' || pre[top-1] == '+' || num[i] - num[pos[top-1]] <= 1 )

{

//去掉该括号

vis[pos[top-1]] = vis[i] = true ;

}

pop();

}

else if( str[i] >= 'A' && str[i] <= 'Z' )

{

num[i]++;

}

else if( str[i] == '+' )

{

ch = str[i] ;

}

else if( str[i] == '-' )

{

ch = str[i] ;

}

}

for( i = 1 , k = 0 ; str[i] ; i++)

if(!vis[i])

ans[k++] = str[i] ;

ans[k] = 0 ;

puts(ans);

}

 

int main()

{

int n ;

scanf("%d",&n); getchar();

while (n--)

{

gets(str+1);

solve();

}

}