算法详述:
(1) bool Math(char exp[ ],intn) :是否匹配,故返回值设计为bool类型,函数功能为输入一个表达式(字符串),故用char exp[ ],本来可在该函数内调用strlen函数计算字符串长度,但在此将strlen函数与Match函数划为同层级,故此函数不调用strlen函数,strlen函数由main函数调用,故用int n
(2) 该算法是在遍历表达式中元素为主体下进行的,故用while(i<n){ },扫描开始,元素若为左括号则进栈,若为右括号,若此时栈非空,就取栈顶元素e,若e为左括号则出栈,否则说明栈空,则match=false.
(3) 为了避免已经发现表达式不匹配后,while继续循环遍历,故将循环判断条件设计为i<n&&match,并使match付初值为true,循环结束后,若栈空,则匹配,若栈不空,则不匹配。
listack.cpp
//链栈基本运算算法
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct linknode
{
ElemType data; //数据域
struct linknode *next; //指针域
} LinkStNode; //链栈类型
void InitStack(LinkStNode *&s)
{
s=(LinkStNode *)malloc(sizeof(LinkStNode));
s->next=NULL;
}
void DestroyStack(LinkStNode *&s)
{
LinkStNode *p=s->next;
while (p!=NULL)
{
free(s);
s=p;
p=p->next;
}
free(s); //s指向尾结点,释放其空间
}
bool StackEmpty(LinkStNode *s)
{
return(s->next==NULL);
}
bool Push(LinkStNode *&s,ElemType e)
{ LinkStNode *p;
p=(LinkStNode *)malloc(sizeof(LinkStNode));
p->data=e; //新建元素e对应的结点p
p->next=s->next; //插入p结点作为开始结点
s->next=p;
return true;
}
bool Pop(LinkStNode *&s,ElemType &e)
{ LinkStNode *p;
if (s->next==NULL) //栈空的情况
return false;
p=s->next; //p指向开始结点
e=p->data;
s->next=p->next; //删除p结点
free(p); //释放p结点
return true;
}
bool GetTop(LinkStNode *s,ElemType &e)
{ if (s->next==NULL) //栈空的情况
return false;
e=s->next->data;
return true;
}
Match.cpp
//判断表达式中的括号是否配对
#include "listack.cpp"
#include <string.h>
bool Match(char exp[],int n)
{
int i=0; char e;
bool match=true;
LinkStNode *st;
InitStack(st); //初始化栈
while (i<n && match) //扫描exp中所有字符
{
if (exp[i]=='(') //当前字符为左括号,将其进栈
Push(st,exp[i]);
else if (exp[i]==')') //当前字符为右括号
{
if (GetTop(st,e)==true)
Pop(st,e);
else match=false; //无法取栈顶元素时(即栈空)表示不匹配
}
i++; //继续处理其他字符
}
if (!StackEmpty(st)) //栈不空时表示不匹配
match=false;
DestroyStack(st); //销毁栈
return match;
}
int main()
{
char exp[]="((1+2)*(5+3))";
if (Match(exp,strlen(exp))==1)
printf("表达式%s括号配对\n",exp);
else
printf("表达式%s括号不配对\n",exp);
return 1;
}
运行截图: