NYOJ 2 括号配对问题(数据结构)

括号配对问题

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 3
描述
现在,有一行括号序列,请你检查这行括号是否配对。
输入
第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
样例输入
3
[(])
(])
([[]()])
样例输出
No
No
Yes
来源
网络
上传者
naonao
    原理:期待的急迫程度

1.按数据结构书上的来,好麻烦,不推荐

#include<stdio.h>
#include<stdlib.h>
typedef struct{
    char m[10000];    
    int last;
}Seqlist;
void Inlist(Seqlist *L){  
    L->last=-1;}       //空栈
void push(Seqlist *L,char num){
    L->m[++(L->last)]=num;}       //输入
void pop(Seqlist *L,char *num){
    *num=L->m[L->last];
    L->last--;
}                    //删栈顶
int isempty(Seqlist *L){
    return (L->last==-1?1:0);
}                  // yes or no

int main()
{
    char tem,t;    
    char *tt=&t;
    int i,ll[5],k=-1,h,flag=1;   //i是测试组数   ll[5]记录yes no
    Seqlist L;    //顺序表L
    Inlist(&L);    建栈
    scanf("%d",&i);    //输入测试组数
    if(i>5)
        return 0;  //测试不超过5组
    while(i-->0)
    {
        flag=1;    
        while(L.last!=-1)
            pop(&L,tt);
        fflush(stdin);  //清除输入缓冲区
        while((tem=getchar())!='\n')
        {        
            if(isempty(&L))    
            {
                if(tem!='('&&tem!='[')    
                {
                    ll[++k]=0;    
                    flag=0;break;
                }
                else
                    push(&L,tem);
            }//empty
            else if(tem==')')
            {
                pop(&L,tt);
                if(*tt!='(')
                {
                    ll[++k]=0;
                    flag=0;break;
                }
            }
            else if(tem==']')
            {
                pop(&L,tt);
                if(*tt!='[')
                {
                    ll[++k]=0;
                    flag=0;break;
                }
            }
            else if(tem=='['||tem=='(')
                push(&L,tem);
        }//while1
        if(flag)
        {
            if(isempty(&L))
            ll[++k]=1;
            else ll[++k]=0;
        }
    }    
    for( h=0;h<=k;h++)    
    {    
        if(ll[h]==0)printf("No\n");    
        if(ll[h]==1) printf("Yes\n");    
    }    
   return 0;    
}


 

2.思想有了再去看3的简化:

  

 #include<stdio.h>  

    #include<string.h>  

    #include<stdlib.h>  

    int main()  

    {  

        char a[10100],b[10100];  

        int n,len,i,top;  

        scanf("%d",&n);  

        while(n--)    

        {  

            scanf("%s",a);  

            len=strlen(a);  

            top=1;   

            b[0]=a[0];    //头结点 

            for(i=1;i<len;i++)  //i从1开始入值 

            {  

                if(a[i]=='('||a[i]=='[')  

                  b[top++]=a[i];//进栈    

                if(a[i]==')')  

                {  

                    if(b[top-1]=='(')   //易错点!!! 

                       top--;//移动栈顶下标   

                    else    

                       b[top++]=a[i];  

                }  

                if(a[i]==']')      //重复 

                {  

                    if(b[top-1]=='[')  

                      top--;  

                    else  

                      b[top++]=a[i];   

                }   

            }  

            if(top==0)  //最后的栈顶下标值值,此时括号全部配对完成 

                printf("Yes\n");  

            else  

                printf("No\n");  

        }  

        return 0;  

    }  

3.简化代码:

#include<stdio.h>
#include<string.h>
int main(){
	int n,i,flag;
	char a[10005];
	scanf("%d\n",&n);
	while(n--){
		flag=1;
		memset(a,0,sizeof(a));
		scanf("%c",&a[0]);
		i=1;
		while(scanf("%c",&a[i])&&(a[i]=='['||a[i]==']'||a[i]=='('||a[i]==')' ) ){//进栈 
			 if(a[i]==']')
			 	if(a[i-1]=='[') i-=2;//配对成功,一对成功,就不用放在栈里了,腾位子给还没配对的 
			 	else   flag=0; //配对失败,No 
			 if(a[i]==')')
			 	if(a[i-1]=='(')  i-=2; //配对成功,一对成功,就不用放在栈里了,腾位子给还没配对的 
				else   flag=0;  //配对失败,No 
			 i++;//若输入为 ‘[ ’或 ‘( ’ ,没有配对 
		}
		if(flag==1&&i==0) printf("Yes\n");//配对一直成功,并且 全部配完Yes 
		else printf("No\n");//其他No 
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值