数据结构-C语言括号匹配问题(栈和计数方式两种思想)

题目描述

现在,有一行括号序列,里面只包含”(“,”)”,”[“,”]”四种符号,请你检查这行括号是否配对。如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的

求解思路

这里提供了两种求解方法:一种是使用栈进行求解;另一种是使用计数器进行求解。下面分别对两种方法进行描述以及给出相应代码。

1.栈
使用栈的时候,可以注意到的就是对于第一次出现的右括号必定与其相邻的左边的括号是一定要匹配的,所以get到这一点就有了思路。
遇到左括号就进栈,当遇到右括号时就与栈顶的元素进行匹配,如果不匹配就输出结果,如果相匹配就出栈,然后重复进行上面判断直至栈空或者匹配失败;
代码如下:

//括号匹配检验-栈
#include<stdio.h>  
#include<stdlib.h>  
#define Stack_size 10000  
typedef struct{  
    char elem[Stack_size];  
    int top;  
} SeqStack;   
void InitStack (SeqStack *S) {  
    S->top = -1;  
}  
int IsEmpty (SeqStack *S) {  
    if (S->top == -1)  return 1;  
    else  
        return 0;  
}  
int Push (SeqStack *S,char x) {  
    if(S->top == Stack_size-1)  return 0;  
    S->top++;  
    S->elem[S->top] = x;  
    return 0;  
}  
int GetTop (SeqStack *S,char *x) {  
    if (S->top == -1)  return 0;  
    else {  
        *x=S->elem[S->top];  
        return 1;  
    }  
}  
int Pop (SeqStack *S,char *x) {  
    if (S->top == -1)  return 0;  
    else {  
        *x=S->elem[S->top];  
        S->top--;  
        return 0;  
    }  
}  
int Match (char a,char b){  
    if (a+1==b||a+2==b)  return 1;  
    else   
        return 0;  
}  
int BracketMatch (char *str){  
    SeqStack S;int i;char ch;  
    InitStack (&S);  
    for (i=0; str[i]!='\0'; i++){  
        switch (str[i]) {  
            case '(':  
            case '[':  
            case '{':  
                Push (&S,str[i]);  
                break;  
            case ')':  
            case ']':  
            case '}':  
                if (IsEmpty (&S) ){  
                    printf("未匹配\n");  
                    return 0;  
                }  
                else {  
                    GetTop (&S,&ch);  
                    if (Match(ch,str[i]))  
                        Pop (&S,&ch);  
                    else{  
                        printf("未匹配\n");  
                        return 0;  
                    }  
                }  
        }  
    }  
    if (IsEmpty (&S) )  
        printf("匹配\n");  
    else  
        printf("未匹配\n");  
    return 0;  
}  
int main(){  
    int n;  
    char a[10000];  
    scanf("%d",&n);  
    while (n--){  
        scanf("%s",a);  
        BracketMatch (a);  
    }  
    return 0;  
}  

2.计数器
定义一个计数器用来判断正反括号的数量,遇见左括号则count+1;
当遇见count不为0且当前字符为右括号时,count–;
若count=0且当前字符为右括号时括号一定不匹配,循环直到EOF,判断count值来看括号是否匹配。
代码如下:

//括号匹配检验-计数器 
#include <stdio.h>  
int main(){  
    int ch;  
    int count1=0;   //大括号{}
    int count2=0;   //中括号[] 
    int count3=0;   //小括号() 
    while((ch=getchar())!='\n'){  
        if(ch=='{'){            //{}
            count1++;  
        }else if(ch=='['){      //[] 
            count2++;  
        }else if(ch==')'){      //()
            count3++;  
        } 
        if(ch=='}'&&count1==0){     //{}{}{}}
            printf("括号不匹配");  
            return 0;  
        }else if(ch==']'&&count2==0){   //[[][]]
            printf("括号不匹配");  
            return 0;  
        }else if(ch==')'&&count3==0){   //(()()())
            printf("括号不匹配");  
            return 0;  
        }       

        if(ch=='}'&&count1!=0){  
            count1--;  
        }else if(ch==']'&&count2!=0){  
            count2--;  
        }else if(ch==')'&&count3!=0){  
            count3--;  
        }         
        /*printf("{}:%d\n",count1);*/
    }
    if(count1==0&&count2==0&&count3==0){          
        printf("括号匹配");
    }else{  
        printf("括号不匹配\n");  
        /*
        printf("{}:%d\n",count1); 
        printf("[]:%d\n",count2); 
        printf("():%d\n",count3); 
        */
    }
    getchar(); 
    return 0;  
}

说明:这里的计数器形式的代码,会把([)]类似于这种形式的括号也算是匹配成功的,这是因为这里计数器方式仅仅顾及到了左括号和右括号的数目和二者的前后关系,就是:([)]和[()]这两种形式在使用计数器计算时其实是差不多的,但是根据这个题目规则的话前者显然是不符合规则的。所以这里的计数器方法有局限性,并没有完全的解决上述问题。

  • 32
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值