括号匹配(栈)

20. 有效的括号 - 力扣(LeetCode)

c++有栈 但是C语言没有

到那时我们可以自己造

这里的代码是直接调用栈,然后调用

等于三个左括号的任意一个 我们就入栈

左括号(入栈)

右括号

取出栈顶数据,出栈并且进行匹配,这里匹配的是不匹配的情况

这里进行方向的判断

因为不匹配可以直接拿结果

栈里面还有数据意味着数量不相等

‘也就是此时进行判断 此时栈是不是为空

图解

  1. 因为每次都是左括号入栈,然后然后才有右括号的,所以我们可以来一个判断,如果入栈半天只有左括号,那么说明也就是第四种情况,直接返回fash就可以
  2. 根据栈的性质,先进先出,我们可以把输入数值的左括号入栈,因为匹配的时候,我们不能去寻找与之匹配的右括号,因为这样可能存在漏掉某一个数组里面的数组就像第三个,所以我们需要进行遍历,所有的左括号入栈,因为的对称的,所以我们可以判定哪些不是与之匹配的右括号,不是就false(这期间记得每次匹配之后,我们需要进行出栈,也就是让栈的第一个数值进行更换,因为我们已经参与匹配并且成功了)
  3. 循环结束之后此时我们进行一个判空,如果是空的说明是,满足条件的,不是空的说明是不满足条件的

代码的实现

#pragma once
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef char STDataType;
typedef struct Stack {
    STDataType* _a; // 首元素的地址
    int _top; // 栈顶,初始化为0,也就是等同于size,初始化为-1,等同于下标
    int _capacity; // 容量
} Stack;
// 初始化栈
void StackInit(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps);
// 初始化栈
void StackInit(Stack* ps) {
    ps->_a = NULL;

    // 这里栈顶初始化为-1和初始化为0是不一样的
    //    0 0 0 0 0 0 0 0 数组
    // -1 0 0 0 0 0 0 0 0 初始化为-1
    //    0 0 0 0 0 0 0 0 初始化为0
    // 初始化为0,也就是等同于size,初始化为-1,等同于下标
    ps->_capacity = ps->_top = 0;
}
// 销毁栈
void StackDestroy(Stack* ps) {
    // 判断为不为空,判断里面有没有数值
    assert(ps && ps->_top);
    free(ps->_a);
    ps->_capacity = ps->_top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data) {
    // 首先判断容量是多少,然后进行扩容
    if (ps->_capacity == ps->_top) {
        // 扩容
        int newapacity = ps->_capacity == 0 ? 4 : 2 * ps->_capacity;
        STDataType* tmp =
            (STDataType*)realloc(ps->_a, newapacity * sizeof(STDataType));
        if (tmp == NULL) {
            perror("StackPush:tmp:error:");
            exit(1);
        }
        // 改变容量大小,指向新空间的头第一个元素位置的地址
        ps->_capacity = newapacity;
        ps->_a = tmp;
    }
    // 插入数值
    ps->_a[ps->_top] = data;
    ps->_top++;
}
// 出栈
void StackPop(Stack* ps) {
    // 判断为不为空,判断里面有没有数值
    assert(ps && ps->_top);
    ps->_top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
    assert(ps && ps->_top);
    return ps->_a[ps->_top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
    assert(ps && ps->_top);
    return ps->_top - 1;
}
// 检测栈是否为空,如果为空返回非零结果(1),如果不为空返回0
int StackEmpty(Stack* ps) {
    assert(ps);
    return ps->_top == 0;
    // 所以,ps->_top == 0 这个表达式的作用是比较栈顶位置 ps->_top 是否等于 0。
    // 如果相等,说明栈为空,表达式结果为 true(在C语言中用 1 表示);
    // 如果不相等,说明栈不为空,表达式结果为 false(在C语言中用 0 表示)
}
bool isValid(char* s) {

    // 创建变量
    Stack ps;
    // 初始化变量
    StackInit(&ps);
    while (*s) {
        // 给出入栈条件,左边括号进行入栈
        if (*s == '[' || *s == '{' || *s == '(') {
            StackPush(&ps, *s);
        } else {
            if (StackEmpty(&ps)) {
                //StackDestroy(&ps);
                return false;
            }
            // 取栈顶
            STDataType ch = StackTop(&ps);
            // 判断不匹配的条件
            if (ch == '[' && *s != ']' || ch == '(' && *s != ')' ||
                ch == '{' && *s != '}') {
                //StackDestroy(&ps);
                return false;
            }
            // 出栈
            StackPop(&ps);
        }
        ++s;
    }
    // 检测栈是否为空,如果为空返回非零结果ture,如果不为空返回false
    bool ret = StackEmpty(&ps);
    return ret;
}

解释:

  1. 栈结构体定义

    • STDataType* _a:指向栈数组的指针,用于存储栈中的元素。
    • int _top:表示栈顶的位置。数组索引从0开始,栈顶位置 _top 初始化为0,表示栈为空。
    • int _capacity:栈的容量,用于存储栈中最多可以存放的元素数量。
  2. 栈操作函数

    • StackInit:初始化栈,将数组指针设置为 NULL,栈顶 _top 和容量 _capacity 都设置为0。
    • StackDestroy:释放栈数组的内存,并将栈顶和容量重置为0。
    • StackPush:入栈操作,将元素添加到栈顶,如果栈已满则先进行扩容。
    • StackPop:出栈操作,移除栈顶的元素。
    • StackTop:获取栈顶元素的值。
    • StackSize:获取栈中元素的数量。
    • StackEmpty:检查栈是否为空。
  3. 括号验证函数 isValid

    • 该函数接收一个字符数组 s 作为参数,用于验证字符串中的括号是否正确配对。
    • 在函数内部,首先创建并初始化了一个 Stack 类型的变量 ps
    • 然后,使用 while 循环遍历字符串 s
      • 如果当前字符是 [{ 或 ((左括号),则将其入栈。
      • 如果当前字符是 ]} 或 )(右括号):
        • 首先检查栈是否为空。如果栈为空,说明没有对应的左括号与之配对,返回 false
        • 否则,获取栈顶元素并与当前字符配对检查。如果配对不成功,返回 false
        • 如果配对成功,执行出栈操作。
    • 在循环结束后,检查栈是否为空。如果栈为空,则说明所有括号都正确配对,返回 true;否则返回 false
  4. 括号配对规则

    • 每种左括号([{()必须与其对应的右括号(]}))配对。
    • 括号的配对必须遵守正确的嵌套顺序。
  5. 注意事项

    • 在 StackPush 函数中,使用了 realloc 进行内存扩容。如果 realloc 失败,程序将输出错误信息并退出。
    • 在 StackDestroy 函数中,使用 assert 宏确保传入的栈指针 ps 不是 NULL,并且栈是非空的。
    • 在 isValid 函数中,没有释放局部栈 ps 的内存,因为 ps 是自动变量,其内存会在函数结束时自动释放。如果 ps 是动态分配的,那么需要在函数末尾调用 StackDestroy 并传递 ps 的地址。

相关推荐

  1. ----7-9 括号匹配

    2024-05-14 05:54:11       23 阅读
  2. 的简单应用:括号匹配

    2024-05-14 05:54:11       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-14 05:54:11       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-14 05:54:11       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-14 05:54:11       82 阅读
  4. Python语言-面向对象

    2024-05-14 05:54:11       91 阅读

热门阅读

  1. 阿里云ACP知识点汇总(36000字版)

    2024-05-14 05:54:11       23 阅读
  2. vim工作模式

    2024-05-14 05:54:11       31 阅读
  3. c 指针基础

    2024-05-14 05:54:11       29 阅读
  4. 缓存:Memcache与 Memcached的

    2024-05-14 05:54:11       26 阅读
  5. Spring boot使用websocket实现在线聊天

    2024-05-14 05:54:11       24 阅读
  6. 大数据技术栈2023:Apache Hadoop和Spark实战

    2024-05-14 05:54:11       28 阅读
  7. ffmpeg 读取流报错: Non-monotonous DTS in output stream

    2024-05-14 05:54:11       20 阅读
  8. Ribbon 策略

    2024-05-14 05:54:11       26 阅读
  9. 前端页面 贴边拖拽 盒子

    2024-05-14 05:54:11       32 阅读
  10. IDEA常用模板

    2024-05-14 05:54:11       30 阅读
  11. 【Pytest官方文档翻译及学习】1.1 安装和入门

    2024-05-14 05:54:11       30 阅读
  12. vue使用pdf

    2024-05-14 05:54:11       27 阅读
  13. vue h5项目预览pdf文件+电子签名

    2024-05-14 05:54:11       30 阅读
  14. 高端手机格局再生变数,华为赋魅、苹果祛魅

    2024-05-14 05:54:11       35 阅读
  15. MySQL编程2

    2024-05-14 05:54:11       32 阅读