题目描述
现在,有一行括号序列,里面只包含”(“,”)”,”[“,”]”四种符号,请你检查这行括号是否配对。如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
求解思路
这里提供了两种求解方法:一种是使用栈进行求解;另一种是使用计数器进行求解。下面分别对两种方法进行描述以及给出相应代码。
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;
}
说明:这里的计数器形式的代码,会把([)]类似于这种形式的括号也算是匹配成功的,这是因为这里计数器方式仅仅顾及到了左括号和右括号的数目和二者的前后关系,就是:([)]和[()]这两种形式在使用计数器计算时其实是差不多的,但是根据这个题目规则的话前者显然是不符合规则的。所以这里的计数器方法有局限性,并没有完全的解决上述问题。