如何判断一串由括号组成的字符串是否合法呢?即每个左括号都有一个对应的右括号与之匹配。
例如:[(())]({()})
首先我们试着分析一下这个字符串:
1.第第一个括号是‘[’,我们希望下一个是‘]’,则可以进行匹配,但是第二个是‘(’,不匹配,所以我们先将第一个括号放在一边。
2,对于第二个括号我们需要‘)’进行匹配,但是第三个括号是‘(’,并不匹配,所以将第二个括号也暂时放在一边
3,我们进行第三个括号的处理,我们需要一个‘)’,第四个括号刚好为‘)’,所以匹配成功,我们继续进行,此时我们需要对前一步中的第二个括号进行处理
4,第二个括号需要‘)’,我们可以发现第五个括号刚好是‘)’,所以匹配成功,我们继续处理前一个未处理的括号,即第一个括号‘[’
5,第一个括号需要‘]’,我们往后处理发现第六个括号是‘]’,匹配成功,继续往后处理
继续后面的步骤同上面的思想即可得。
对于上述过程,我们可以使用栈的思想进行实现。
我们可以进行一下演示:处理字符串:[(())]({()})
步骤 | 要处理的字符 | 动作 | 栈中内容 | ||||
1 | ‘[’ | 栈中为空,所以将它压入栈中 |
栈 | ||||
2 | ‘(’ | 与栈顶元素‘[’不匹配,将它压入栈中,暂不处理 |
栈 | ||||
3 | '(' | 栈顶元素为‘(’,和当前处理字符不匹配,所以压入栈中 |
栈 | ||||
4 | ')' | 与栈顶元素‘(’,匹配,所以将栈顶元素‘(’出栈,与当前处理字符配对 |
栈 | ||||
5 | ‘)’ | 与栈顶元素‘(’,匹配,所以将栈顶元素‘(’出栈,与当前处理字符配对 |
栈 | ||||
6 | ']' | 与栈顶元素‘[’,匹配,所以将栈顶元素‘]’出栈,与当前处理字符配对 |
栈 | ||||
7 | '(' | 当前栈为空,所以将它压入栈中,暂不处理 |
栈 | ||||
8 | ‘{’ | 栈顶元素为‘(’,和当前处理字符不匹配,所以压入栈中 |
栈 | ||||
9 | ‘(’ | 栈顶元素为‘{’,和当前处理字符不匹配,所以压入栈中 |
栈 | ||||
10 | ‘)’ | 与栈顶元素‘(’,匹配,所以将栈顶元素‘(’出栈,与当前处理字符配对 |
栈 | ||||
11 | ‘}’ | 与栈顶元素‘{’,匹配,所以将栈顶元素‘{’出栈,与当前处理字符配对 |
栈 | ||||
12 | ‘)’ | 与栈顶元素‘(’,匹配,所以将栈顶元素‘(’出栈,与当前处理字符配对 |
栈 | ||||
13 | 处理结束栈为空 | 所以可判断当前括号字符串合法 |
栈 |
所以我们对这个字符串处理的结果就是,如果最后处理结束后栈中元素为空,就代表所有括号均合法匹配到,字符串是合法的。
当然对于不合法的情况有,如果读入的右括号和栈顶元素左括号不匹配就代表匹配失败;如果匹配结束,栈中仍有元素则也表示字符串不合法。
代码实现如下:
#include<stdio.h>
#include"malloc.h"
typedef struct LinkNode{
char c;
struct LinkNode *next;
}LinkNode,*LiStack;
//带头节点的栈初始化
bool InitStack(LiStack &Ls){
Ls=(LinkNode *)malloc(sizeof(LinkNode));
if(Ls==NULL)return false;
Ls->next=NULL;
return true;
}
//进栈操作
void Push(LiStack &Ls,char c) {
LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
s->c=c;
s->next=Ls->next;
Ls->next=s;
}
//出栈操作
bool Pop(LiStack &Ls,char &c){
if(Ls->next==NULL)return false;
c=Ls->next->c;
LinkNode *q=Ls->next;
Ls->next=q->next;
free(q);
return true;
}
//判断栈是否为空
bool IsEmpty(LiStack &Ls)
{
return Ls->next==NULL;
}
//进行括号匹配
bool IsCatch(){
char c;
LiStack Ls;
if(InitStack(Ls));{
while((c=getchar())!='\n'){
if(c=='('||c=='['||c=='{'){
Push(Ls,c);
}
else{
char d;
if(!Pop(Ls,d))return false;
if(d!='('&&c==')')return false;
if(c=='['&&d!=']')return false;
if(c=='{'&&d!='}')return false;
}
}
return IsEmpty(Ls);
}
return false;
}
int main(){
if(IsCatch()){
printf("成功\n");
}
else printf("失败\n");
return true;
}