C语言-数据结构 括号匹配(链栈实现)

        在括号匹配中,我们会利用到栈,如果不知道栈的可以先去看下栈的思想和实现,再来看本文,这里就不再讨论栈的实现了,在括号匹配问题中,失败的情形有三种:

        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;
}

        运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值