括号匹配的检验
一、题目
- 问题描述:
假设表达式中允许有两种括号:圆括号和方括号,其嵌套的顺序随意,即(()[ ])或[([ ] [ ])]等为正确格式,[( ])或(((]均为不正确的格式。检验括号是否匹配的方法可用“期待的紧迫程度”这个概念来描述。例如:考虑下列的括号序列:
[ ( [ ] [ ] ) ]
1 2 3 4 5 6 7 8
当计算机接受了第1个括号以后,他期待着与其匹配的第8个括号的出现,然而等来的却是第2个括号,此时第1个括号“[”只能暂时靠边,而迫切等待与第2个括号相匹配的 第7个括号“)”的出现,类似的,因只等来了第3个括号“[”,此时,其期待的紧迫程度较第2个括号更紧迫,则第2个括号只能靠边,让位于第3个括号,显然第3个括号的期待紧迫程度高于第2个括号,而第2个括号的期待紧迫程度高于第1个括号;在接受了第4个括号之后,第3个括号的期待得到了满足,消解之后,第2个括号的期待匹配就成了最急迫的任务了,…… ,依次类推。可见这个处理过程正好和栈的特点相吻合。
-
基本要求:
读入圆括号和方括号的任意序列,输出“匹配”或“此串括号匹配不合法”。 -
测试数据:
输入([ ]()),结果“匹配”
输入 [( )],结果“此串括号匹配不合法” -
实现提示:
设置一个栈,每读入一个括号,若是左括号,则作为一个新的更急迫的期待压入栈中;若是右括号,并且与当前栈顶的左括号相匹配,则将当前栈顶的左括号退出,继续读下一个括号,如果读入的右括号与当前栈顶的左括号不匹配,则属于不合法的情况。在初始和结束时,栈应该是空的。 -
选作内容
考虑增加大括号的情况。
二、代码实现
代码如下(示例):
#include "iostream"
#include "stdlib.h"
#include "string.h"
#define MAXSIZE 100
#define ERROR 0
#define OK 1
using namespace std;
typedef int Status;
typedef struct{
char *base;
char *top;
int stacksize;
}SqStack;
Status InitStack(SqStack &S){ //初始化一个顺序栈
S.base = new char[MAXSIZE];
if(!S.base) exit(ERROR);
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}
Status Push(SqStack &S,char e){ //入栈函数
if(S.top - S.base == S.stacksize) return ERROR;
*S.top++ = e;
return OK;
}
Status Pop(SqStack &S,char &e){ //出栈函数
if(S.top == S.base) return ERROR;
e = *--S.top;
return OK;
}
char GetTop(SqStack S){ //取栈顶元素
if(S.top != S.base) return *(S.top - 1);
}
Status StackEmpty(SqStack S){ //判断顺序栈是否为空
if(S.base==S.top){
return true;
}
return false;
}
int main(){
SqStack S;
char str[20],e,c;
int t;
InitStack(S);
cout<<"输入要检验的式子:";
cin>>str;//输入要检验的式子
t = strlen(str);//得出式子字符串长度(后面循环用)
if(str[0] == ')' || str[0] == ']' || str[0] == '}'){
cout<<"此串括号匹配不合法"<<endl;
} //判断第一个字符;(特殊,需要单独判断)
for(int i=1;str[i] !='\0';i++){//判断除第一个字符外的所有字符
e = str[i];
c = GetTop(S); //取栈顶元素
switch(e){// 选择函数来进行判断,后续操作
case '(':Push(S,e); break;
case '[':Push(S,e); break;
case '{':Push(S,e); break;
case ')':if(c == '(') Pop(S,e);
else cout<<"此串括号匹配不合法"<<endl;
break;
case ']':if(c == '[') Pop(S,e);
else cout<<"此串括号匹配不合法"<<endl;
break;
case '}':if(c == '{') Pop(S,e);
else cout<<"此串括号匹配不合法"<<endl;
break;
default:break;
}
if((i+1 == strlen(str)) && StackEmpty(S)) cout<<"此串括号匹配"<<endl;
//给匹配结果写条件。
}
return 0;
}
三、实例运行
输入:()
结果:
输入:(2+3)
结果:
输入:((]
结果:
总结
这道题,利用了顺序栈来进行解决。将“( [ { ) } ]”等符号通过switch函数选择的方法来进行是否入栈,取栈顶元素的比较,出栈等等…的限定条件来进行结果判断。
其实利用for函数if函数也能进行实现但是通过最优的解法和代码复杂程度,选择了switch函数。