括号匹配(栈)

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,如果不为空返回falsebool 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 的地址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/697332.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣【旋转函数】python

如果直接用暴力的话&#xff0c;只能过4个样例好像&#xff0c;超时 因此得用递推公式 F1F0前n-1个数-(n-1)*第n个数 F0sum(nums)-n*第n个数 nlen(nums) ans[]#定义一个存最大值值的列表 ss sum(nums) dm 0 for j in range(n):dm j * nums[j] ans.append(dm) print(dm) n…

树莓派对FPGA板子上的流水灯程序的控制

文章目录 一 树莓派使用教程二 树莓派串口代码三 Verilog代码四 quartus引脚绑定五 运行效果总结 分别在DE2-115开发板和树莓派上编写串口通信程序&#xff0c; 实现树莓派串口指令对FPGA板子上的流水灯程序的控制&#xff0c;控制方式自定。 一 树莓派使用教程 参考&#xff…

重发布与路由决策

单点重发布 将A协议--->B协议 [r2-rip-1]import-route ospf 1 将静态---->B协议 [r2-rip-1]import-route static 将直连---->B协议 [r2-rip-1]import-route direct 双点重发布 路由回馈&#xff1a;指的是从某协议传出的路由信息又被传回该协议中。可以引起选路…

python数据分析——seaborn绘图1

参考资料&#xff1a;活用pandas库 matplotlib库是python的和兴绘图工具&#xff0c;而seaborn基于matplotlib创建&#xff0c;它为绘制统计图提供了更高级的接口&#xff0c;使得只用少量代码就能生成更美观、更复杂的可视化效果。 seaborn库和pandas以及其他pydata库&#xf…

第十五节:贪心算法(下)

一 、 贪心算法的解题套路实战一&#xff08;最多的会议宣讲场次&#xff09; 1.1 描述 一些项目要占用一个会议室宣讲&#xff0c;会议室不能同时容纳两个项目的宣讲。 给你每一个项目开始的时间和结束的时间 你来安排宣讲的日程&#xff0c;要求会议室进行的宣讲的场次最多。…

vue:网页icon无法显示

logo文件放在public文件夹下&#xff0c;在html里设置icon。 本地源码运行后发现网页icon无法显示我们设置的logo&#xff0c;而是显示了浏览器默认icon。 这个问题不需要解决&#xff0c;部署后网页icon显示就正常了。

通过ip addr命令无法获取到ip地址,无法ping通百度

问题 今天通过VM安装CentOS虚拟机时&#xff0c;安装完成后&#xff0c;想查看ip地址&#xff0c;使用ip addr命令&#xff0c;发现没有展示网络ip地址&#xff0c;ping百度也不通。 解决方案 CentOS使用网络配置文件来设置网络接口的参数&#xff0c;出现这个问题说明网络的…

华为认证存储HCIE有用吗?

首先&#xff0c;对于个人来说&#xff0c;获得华为存储认证可以证明其具备信息存储技术的专业能力 1.专业认可&#xff1a;获得华为存储认证&#xff0c;尤其是HCIE-Storage级别的证书&#xff0c;意味着持有者对信息存储技术有着全面深入的理解&#xff0c;能够设计、部署、…

spring cloud微服务example 入门第一个例子

新建Maven工程 删除src目录&#xff0c;修改poml.xml <modelVersion>4.0.0</modelVersion><groupId>org.example</groupId> <artifactId>SpringCloud_example</artifactId> <version>1.0-SNAPSHOT</version> <packaging&g…

苹果cms:伪静态设置教程

官方默认的网站模式是动态模式&#xff0c;动态模式下链接中自带有“index.php”想要去除网站链接中的index.php&#xff0c;首先需要开启网站的模式为伪静态模式。这样比动态模式那一长串的链接看着也舒服一些&#xff0c;最重要的是迎合搜索引擎的喜好加快收录提高排名。 1、…

【CSP CCF记录】202206-2 寻宝!大冒险!

题目 过程 思路 1.绿化图坐标边界太大&#xff0c;不能直接用矩阵表示&#xff0c;可以用一个二维数组存储有树坐标的x,y值。 定义两个数组&#xff1a;绿化图arr[1005][2]、宝藏图数组b[55][55] 2. 依据条件&#xff0c;从绿化图中第一棵树的坐标开始区域遍历。统计绿化图…

Java进阶10 IO流

Java进阶10 IO流 IO流就是数据传输。I为input的缩写&#xff0c;表示输入读取&#xff1b;O为out的缩写&#xff0c;表示输出写出。 一、IO流体系结构 ♥巧记区分tips&#xff1a;以Stream结尾的是字节流&#xff1b;以Reader、Writer结尾的都是字符流 二、字节输出流FileOu…