16.括号匹配的检验(**)
描述:
从键盘输入任意括号序列,编程判断括号是否匹配。假设允许有三种括号:圆括号()、方括号[]和花括号{},其嵌套的顺序随意。
基本要求及提示:
为了正确检验输入序列的括号匹配问题,要使用栈结构来实现。
(1)在检验算法中建立一个栈,读入圆括号、方括号和大括号组成的序列;
(2)若是左括号直接入栈,等待同类的右括号与之匹配;若读入的是右括号,不入栈,若与当前栈顶的左括号为同类括号,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况;
(3)如果序列已读尽,而栈中仍有待匹配的左括号,或读入一个右括号,而栈已空,则均属不合法情况。
(4)当输入序列与栈同时变空,则说明所有括号完全匹配。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OK 1
#define FALSE -1
#define TRUE 1
#define MAXSIZE 100
typedef struct node
{
char data[MAXSIZE];
int top;
} SeqStack;
int menu_select();
void InitStack(SeqStack * S);
int Push(SeqStack * S, char x);
int Pop(SeqStack * S, char * x);
int GetTop(SeqStack * S, char * x);
void introduce();
int IsEmpty(SeqStack * S);
int Match(char a, char b);
int menu_select() // 菜单驱动程序
{
int sn;
printf(" 括号匹配
"); // 显示菜单
printf("==============================
");
printf(" 1、题目介绍
");
printf(" 2、括号匹配
");
printf(" 0、退出
");
printf("==============================
");
printf(" 请选择0--2: ");
for (;;) // 菜单功能选择
{
scanf("%d", &sn);
getchar();
if (sn < 0 || sn>2)
{
printf("
输入选择错误,请重新选择 0--2: ");
while (getchar() != '
');
}
else
break;
}
return sn;
}
/*
TODO: 括号匹配的检验
功能描述:利用堆栈技术来检验该字符串中的括号是否匹配
循环逐一扫描该字符串,判断字符串中的括号是否匹配
若是左括号直接入栈,等待同类的右括号与之匹配;若读入的是右括号,不入栈,若与当前栈顶的左括号为同类括号,则二者匹配,将栈顶的左括号出栈,
若与当前栈顶的左括号为不同类括号,返回2
如果序列已读尽,而栈中仍有待匹配的左括号,返回3,读入一个右括号,而栈已空,返回1
当输入序列与栈同时变空,则说明所有括号完全匹配,返回0
参数说明: str为输入的字符串
返回值说明: 括号匹配的结果,0:表示括号匹配,1:表示右括号多余,2:表示对应的括号不同类,3:表示左括号多余
*/
int BracketMatch(char *str)
{
SeqStack* compstack = (SeqStack*)malloc(sizeof(SeqStack));
InitStack(compstack);
int i = 0;
char top;
while(str[i]!=0)///这个程序内部有非常多的逻辑判断,每个都要想清楚,明确每个if语句的判断条件后,翻译题意即可
{
if(str[i]!='(' && str[i]!=')' && str[i]!='[' && str[i]!=']' && str[i]!='{' && str[i]!='}')//如果是其他字符,就略过
{
i++;
continue;
}
if((str[i]==')' || str[i]==']' || str[i]=='}') && IsEmpty(compstack) == 1)//如果扫描到右括号且栈已空,就返回1
{
return 1;
}
else if(str[i]=='(' || str[i]=='[' || str[i]=='{')//如果扫描到左括号,就直接入栈
{
Push(compstack, str[i]);
i++;
continue;
}
else if(str[i]==')' || str[i]==']' || str[i]=='}')//如果扫描到右括号
{
GetTop(compstack, &top);
if((top == '(' && str[i]==')') || (top == '[' && str[i]==']') || (top == '{' && str[i]=='}'))//栈顶元素对比当前元素,是否配对
{
Pop(compstack, &top);//是的话,弹出
i++;
continue;
}
else
{
return 2;//否则返回2,表示不配对
}
}
}
if(IsEmpty(compstack) != 1)//如果栈未空,序列已空,
{
return 3;//返回3,左括号多余
}
else//否则,返回0,完全匹配
{
return 0;
}
}
void InitStack(SeqStack * S)
{
S->top = -1;
}
int Push(SeqStack * S, char x)
{
if (S->top == MAXSIZE - 1)
return FALSE;
S->top++;
S->data[S->top] = x;
return TRUE;
}
int Pop(SeqStack * S,char * x)
{
if (S->top == -1)
return FALSE;
else
{
*x = S->data[S->top];
S->top--;
return TRUE;
}
}
int GetTop(SeqStack * S, char * x)
{
if (S->top == -1)
return FALSE;
else
{
*x = S->data[S->top];
return TRUE;
}
}
void introduce()
{
printf("利用堆栈技术检验该字符串是否匹配
");
}
int IsEmpty(SeqStack * S)
{
if (S->top == -1)
return 1;
else
return 0;
}
int Match(char a, char b)
{
if ((a == '(' && b==')' )||(a=='[') && b==']'||(a=='{' && b=='}'))
return 1;
else
return 0;
}
int main()
{
char str[MAXSIZE];
for (;;) // 无限循环,选择0 退出
{
switch (menu_select()) // 调用菜单函数,按返回值选择功能函数
{
case 1:
introduce();
break;
case 2:
printf("请输入字符串");
fgets(str,MAXSIZE,stdin);
switch(BracketMatch(str))
{
case 0:
printf("括号匹配!
");
break;
case 1:
printf("
右括号多余!
");
break;
case 2:
printf("
对应的括号不同类!
");
break;
case 3:
printf("左括号多余!
");
break;
}
break;
case 0:
printf(" 再见!
"); //退出系统
return 0;
} // switch语句结束
} // for循环结束
} // main()函数结束