poj1690 (Your)((Term)((Project))) (括号配对)

来源:互联网 发布:短信轰炸java源码 编辑:程序博客网 时间:2024/05/18 22:13

原题: http://poj.org/problem?id=1690

思路:根据括号配对原则 得出每一个括号的位置k[i]=j 表示左半括号(在位置i,右半括号)在位置j
我们根据'('出现的顺序,从左到右遍历每一个括号,对于每一个括号有下面四种情况要删除这个括号:
1. 如果'('左边全是空格,或是在第一个字符,或者 '('   ')'中间只隔了一个数字即 j-i==2 ,这个括号直接删除
2.如果'('左边是'+',删除这个括号
3.如果'('左边是'(',删除这个括号
4.如果'('左边是'-',向中间遍历,看是否有另一对括号在中间即这种情况((...)),有的话,去掉这个外层的括号
删除的方式就是置为空格' '。在最后输出的时候,直接输出非空格的字符就可以了。

#include<cstdio>#include<vector>#include<memory.h>using namespace std;int k[126];int strlen(char *from){int i=0;while(from[i]!='\0'){i++;}return i;}int main(){int t;scanf("%d",&t);getchar();while(t--){memset(k,-1,sizeof(k));vector<int>v;char str[300];char str2[300];int index=0;gets(str);int len=strlen(str);int pos=0;for(int i=0;i<len;i++){if(str[i]!=' '){str2[index]=str[i];//删掉空格 if(str2[index]=='(') //括号配对 {v.push_back(index);}if(str2[index]==')'){k[v.back()]=index;v.pop_back();pos++;}index++;} }str2[index]='\0';//删除空格之后的字符串 //从左到右遍历每一个括号 for(int i=0;i<126;i++){if(k[i]==-1){continue;}int tmpl=i;int tmpr=k[i];//情况1.  if(tmpl==0)//是首个,去掉 {str2[tmpl]=' ';str2[tmpr]=' '; continue; }//情况1. if(tmpr-tmpl==2){str2[tmpl]=' ';str2[tmpr]=' '; continue;}int l=tmpl-1;int r;while(str2[l]==' ' && l >=0)//向左扫描 {l--;}if(l==-1){       //情况1. str2[tmpl]=' ';str2[tmpr]=' ';}else if(str2[l]=='+'){//情况2. str2[tmpl]=' ';str2[tmpr]=' '; }else if(str2[l]=='('){ //情况3. str2[tmpl]=' ';str2[tmpr]=' '; }else if(str2[l]=='-'){//情况4. l=tmpl+1;r=tmpr-1;while(str2[l]==' ' && l<r)//向右扫描{l++;}while(str2[r]==' '&& r>l)//向左扫描{r--;}if(k[l]==r)//里面也是一个括号,去掉  {str2[tmpl]=' ';str2[tmpr]=' '; }}} for(int i=0;i<index;i++){if(str2[i]!=' ')//输出非空格 {printf("%c",str2[i]);}}printf("\n");}return 0;}