一、问题概述
假设表达式中允许包含两种括号:圆括号及方括号,其嵌套顺序任意即(()[])或者[([])]等均为正确格式,[(])或者([)]为不正确格式。现在需要解决输入一段字符串,检测其括号是否匹配即是否成对出现。
二、基本思路
最后出现的左括号最先被匹配(与栈的后进先出LIFO相同)
- 遇到左括号入栈
- 遇到右括号就从栈顶弹出一个左括号与之匹配(出栈)
三、实现流程
四、完整代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define MaxSize 100
typedef struct {
char data[MaxSize];
int top;
}SqStack;
//初始化栈
void InitStack(SqStack *S) {
S->top = -1;
}
//判栈空
bool IsEmpty(SqStack S) {
if (S.top == -1) {
return true;
}
else {
return false;
}
}
//入栈
void Push(SqStack *S, char x) {
if (S->top == MaxSize-1) {
printf("栈已满");
return;
}
S->top += 1;
S->data[S->top] = x;
}
//栈顶元素出栈,用x返回
void Pop(SqStack *S, char *x) {
if (S->top == -1) {
printf("栈已满");
return;
}
*x = S->data[S->top];
S->top -= 1; //S->top=S->top+1;
}
//匹配算法
bool bracketCheck(char str[], int length) {
SqStack S;
InitStack(&S);//初始化
for (int i = 0; i < length; i++) {
if (str[i] == '(' || str[i] == '[' || str[i] == '{') {
Push(&S, str[i]);//扫描到左括号就进栈
}
else {
if (IsEmpty(S)) { //扫描到右括号,栈空
return false;//匹配失败
}
char topElem;//保存弹出的栈顶元素
Pop(&S, &topElem);//栈顶元素出栈
if (str[i] == ')' && topElem != '(') {
return false;
}
if (str[i] == '}' && topElem != '{') {
return false;
}
if (str[i] == ']' && topElem != '[') {
return false;
}
}
}
return IsEmpty(S);
}
int main() {
char c[MaxSize];
printf("请输入需要判断的括号:");
scanf_s("%s", c);
int len = strlen(c);
printf("当前输入括号的个数为:%d", len);
printf("现在开始判断...");
if (bracketCheck(c, len)) {
printf("匹配成功!");
}
else {
printf("匹配失败!");
}
return 0;
}
运行结果
报错分析
我这里使用的编译软件是vs2019,发现正常输入的字符串会有报错,引发异常的原因为0x7A3FEF8C (ucrtbased.dll)处(位于 Project1.exe 中)引发的异常: 0xC0000005: 写入位置 0x00500000 时发生访问冲突。
经查阅得知,该问题是vs2019编译器中scanf_s函数的问题(预防原scanf函数的数组越界问题,需提供数组名及数组长度即可编译通过。
#define MaxSize 100
char name[MaxSize];
scanf_s("%s", name, MaxSize);
修改后