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

原题: 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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值