在括号匹配中,我们会利用到栈,如果不知道栈的可以先去看下栈的思想和实现,再来看本文,这里就不再讨论栈的实现了,在括号匹配问题中,失败的情形有三种:
1. 左括号数量>右括号数量
2.左括号!=右括号
3.左括号数量<右括号数量
这是具体的情况:
那么怎么对这三种情况失败的情况进行判断,我们建立一个for循环遍历每个字符,当我们遇到左括号就直接入栈,当我们遇到右括号就直接进行判断,右括号不入栈切记,右括号判断很巧妙,循环中排除两种不匹配的情况(1. 右括号多 2.左右括号不匹配),最后返回的结果那里通过判断栈是否为空巧妙得知括号匹配结果,如果不为空(3.说明左括号多,加上前面循环中判断匹配失败的两种情况,三种匹配失败的情况都考虑到了),如果栈为空那么说明全部括号匹配正确!!!建议手动把str1、str2、str3三种失败情况跟着代码走一遍容易懂,具体代码看下面
匹配函数代码:
遇到左括号进栈:
遇到右括号进行判断,右括号不进栈:
循环完成后返回的结果:
全部实现代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Status int
#define OK 1
#define Error 0
#define OVERFLOW 1
// 定义栈的结构体
typedef struct Stack {
char Element; // 栈元素,存储字符
struct Stack* next; // 指向下一个栈元素的指针
} Stack;
// 初始化栈
Status InitStack(Stack** Head) {
*Head = (Stack*)malloc(sizeof(Stack)); // 分配内存给栈头节点
if (!(*Head)) exit(OVERFLOW); // 如果内存分配失败,退出程序
(*Head)->next = NULL; // 初始化栈为空
return OK;
}
// 获取栈顶元素
Status GetTop(Stack* Head, char* e) {
if (!Head->next) return Error; // 如果栈为空,返回错误
*e = Head->next->Element; // 获取栈顶元素
return OK;
}
// 入栈操作
Status Push(Stack* Head, char e) {
if (!Head) return Error; // 如果栈头指针无效,返回错误
Stack* p = (Stack*)malloc(sizeof(Stack)); // 分配内存给新栈元素
if (!p) return OVERFLOW; // 如果内存分配失败,返回溢出
p->Element = e; // 设置栈元素值
p->next = Head->next; // 将新节点的 next 指针指向原栈顶
Head->next = p; // 更新栈头指针的 next 指向新节点
return OK;
}
// 出栈操作
Status Pop(Stack* Head) {
if (!Head) return Error; // 如果栈头指针无效,返回错误
if (!Head->next) return Error; // 如果栈为空,返回错误
Stack* p = Head->next; // 获取栈顶元素
Head->next = p->next; // 更新栈头指针的 next 指向原栈顶的下一个元素
free(p); // 释放栈顶元素的内存
return OK;
}
// 判断栈是否为空
Status isEmpty(Stack* Head) {
if (!Head->next) return OK; // 如果栈为空,返回 OK
return Error; // 否则返回 Error
}
// 括号匹配函数
int BracketMatch(const char str[]) {
Stack* stack;
InitStack(&stack); // 初始化栈
for (int i = 0; i < strlen(str); i++) {
char topElement;
if (str[i] == '(') {
Push(stack, ')');
}
else if (str[i] == '[') {
Push(stack, ']');
}
else if (str[i] == '{') {
Push(stack, '}');
}
else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {
if (isEmpty(stack)) {
return Error; // 栈空时遇到右括号,匹配失败
}
GetTop(stack, &topElement);
if (topElement != str[i]) {
return Error; // 括号不匹配
}
Pop(stack); // 括号匹配,出栈
}
}
return isEmpty(stack); // 最终检查栈是否为空
}
// 判断括号匹配结果
void IsSuccess(const char str[]) {
int flag = BracketMatch(str);
if (flag == OK) {
printf("字符串: %s\n", str);
printf("匹配成功!\n");
}
else {
printf("字符串: %s\n", str);
printf("匹配失败!\n");
}
}
int main() {
char str1[] = "(([{}])"; // 匹配失败
char str2[] = "[{}}"; // 匹配失败
char str3[] = "([{}])))"; // 匹配失败
char str4[] = "([{}])"; // 匹配成功
IsSuccess(str1);
IsSuccess(str2);
IsSuccess(str3);
IsSuccess(str4);
return 0;
}
运行结果如下: