括号匹配问题是栈应用的一个经典场景,原理比较简单:
- 括号匹配原理
假设表达式中允许包含两种括号:圆括号和方括号,其嵌入的顺序随意,即([ ] ( ))或[([ ] [ ])]等为正确的格式,[(])或([())或(())]均为不正确的格式。检验括号是否匹配的方法可用“期待的急迫程度”这个概念来描述。
由此,在算法中设置一个栈,每读入一个括号,若是右括号,则或者使置于栈顶的最击破的期待得以消解,或者是不合法的情况;若是左括号,则作为一个新的更急迫的期待压入栈中,自然使原有的在栈中的所有未消解的期待的急迫性都降了一级。另外,在算法的开始和结束时,栈都应该是空的。
- 具体实现
假设一个算术表达式中包含圆括号、方括号两种类型的括号,试编写一个判断表达式中括号是否匹配的程序,匹配返回Match succeed!,否则返回Match false!。
例
[1+2*(3+4*(5+6))]括号匹配
(1+2)(1+2[(1+2)+3)括号不匹配
输入:
包含圆括号、方括号两种类型括号的算术表达式
输出:
匹配输出Match succeed!
不匹配输出 Match false!
例
输入[1+2* (3+4*(5+6))]
输出Match succeed!
在这里插入代码片#include <stdio.h>
#include <stdlib.h>
#define Stack_Init_Size 100
#define STACK_SIZE_INCREASEMENT 10
typedef char SElement;
typedef struct{
SElement *base;
SElement *top;
int stacksize;
}SqStack;
void InitStack(SqStack & s){
//构造一个栈s
s.base = (SElement * )malloc(Stack_Init_Size * sizeof(SElement));
if(!s.base) exit(0);
s.top = s.base;
s.stacksize = Stack_Init_Size;
}
void Push(SqStack & s, SElement e){
if(s.top - s.base >= Stack_Init_Size){ //如果栈满,则增加栈的容量
s.base = (SElement *)realloc(s.base, (s.stacksize + STACK_SIZE_INCREASEMENT) * sizeof(SElement));
if(!s.base) exit(0);
s.stacksize += STACK_SIZE_INCREASEMENT;
}
* s.top++ = e;
}
void Pop(SqStack & s){
if(s.base == s.top) exit(0);
else{
s.top -= 1;
s.stacksize -= 1;
}
}
void BracketMatch(SqStack s){
char c;
while((c = getchar() ) != '\n'){
if(c == '[' || c == '(') Push(s, c); //压入更急迫的元素
else if(c == ']'){
if(*(s.top - 1) == '[') //找到匹配的括号,栈顶元素出栈
Pop(s);
else{
printf("Match False!");
exit(0);
}
}
else if(c == ')'){
if(*(s.top - 1) == '(') //找到匹配的括号,栈顶元素出栈
Pop(s);
else{
printf("Match False!");
exit(0);
}
}
}
if(s.top == s.base) printf("Match Succeed!"); //最后检查条件
else
printf("Match False!");
}
int main(){
SqStack bracket;
InitStack(bracket);
BracketMatch(bracket);
return 0;
}
在编写的过程中,遇到的问题:
1.c语言中没有引用参数的概念,所以我在 InitStack(SqStack & s)函数中这样写参数表列是有问题的,最后是通过将.c文件保存成.cpp文件,才允许这么实现。
2.如果写成InitStack(SqStack s),且保存成.c文件,那么在InitStack()函数中对s的操作将不会生效。