数据栈的应用——括号匹配法
括号匹配法是数据栈的应用里面比较典型的一个,要实现括号匹配法首先我们就要对数据栈的相关理论有所熟悉。
一、数据栈的相关内容回顾
首先我们知道栈是只允许我们在栈顶进行操作的一种线性表,在数据栈当中我们定义的相关数据域有:
头指针:top(指向栈顶位置,用伪指针来进行定义);
数据数组:data[ ](存入栈元素)。
二、括号匹配法中所需要的栈的相关操作
1、入栈( push(&s, e) ):在栈未满的状态下进行将元素 e 压入栈的操作。
2、出栈( pop(&s,&e) ):在栈非空的状态下进行将栈顶元素 保存在e内并取出栈的操作。
3、判断空栈(stackEmpty(s)):判断是否为空栈,空栈返回1,非空返回0。
三、括号匹配法的实现
1、对括号匹配的相关分析:
假设有以下含括号的表达式:
(1)合法的表达式:{a*[a*(b+c)]},括号出现顺序为:{[()]}
(2)不合法的表达式:{a*[a*(b+c])},括号出现顺序为:{[(])}
可以发现:
括号匹配时,左括号出现的序列{[(与对应的右括号出现的序列)]}刚好相反;而当括号不匹配时,则不是。也就是说我们可以通过判断几组序列是否相反,即可判断括号是否匹配。
2、实现算法的相关思想
由我们的分析不难得出一下的算法思想:
(1)如果遇到的是左括号,则把这个括号压入栈顶;
(2)如果遇到的是右括号,则尝试将栈顶元素与之进行括号匹配,若成功,则出栈栈顶元素,否则,括号匹配失败;
(3)处理完所有括号后,栈不为空,则括号不匹配,否则,括号匹配。
3、由此我们不难得出我们的相关代码实现:
int isValid(SeqStack *s,char *exp)//定义isvalid函数来实现对括号匹配的实现
{
char e,c;
int i;
for(i=0;i<N;i++)
{
c=*(exp+i);
if(c=='('||c=='['||c=='{')//判断是否为左括号,若是则压入栈
{
push(s,c);
}
else
{
if(stackEmpty(*s))//判断数据栈是否为空,若空则结束本次循环
{
continue;
}
if(c==')'||c==']'||c=='}')//判断是否为右括号,若是则将栈顶元素取出进行检测是否匹配
{
pop(s,&e);
if(e!='('&&c==')')
{
return 0;
}
if(e!='['&&c==']')
{
return 0;
}
if(e!='{'&&c=='}')
{
return 0;
}
}
}
}
return stackEmpty(*s);//返回是否为空栈,避免出现左括号比右括号多的情况
}