栈和队列oj题——20. 有效的括号

在这里插入图片描述

个人主页:晓风飞
专栏:数据结构|Linux||C语言


文章目录

  • 解题核心思路
  • 使用STInit(&st);初始化栈。
  • 遍历字符串:
  • 处理左括号:
  • 处理右括号:
  • 字符串遍历完成:
  • 使用STDestroy(&st);销毁栈,释放资源。
  • 以下是栈的实现:

要做题目的点击这里–>栈和队列oj题——20. 有效的括号

解题核心思路

当解决使用栈来检查字符串中括号平衡的问题时,主要思路是遵循左括号与右括号的配对规则。我们使用一个栈来跟踪所有未闭合的左括号,并在遇到相应的右括号时检查是否有匹配的左括号。以下是详细的解题思路:

使用STInit(&st);初始化栈。

这是为了存储遇到的左括号。

 ST st;STInit(&st); // 初始化栈

遍历字符串:

创建一个空栈,用于存储遇到的左括号。
遍历字符串中的每个字符:
while(*s)循环遍历字符串中的每个字符。

处理左括号:

if(*s == ‘{’ || *s == ‘[’ || *s == ‘(’)检查当前字符是否为左括号。
如果是,使用STPush(&st, *s);将其压入栈中。

if(*s == '{' || *s == '[' || *s =='('){STPush(&st,*s);// 如果是左括号,压入栈}

处理右括号:

如果当前字符是右括号,首先检查栈是否为空:if(STEmpty(&st))。
如果栈为空,使用STDestroy(&st);销毁栈并返回false。这表示没有相应的左括号与之匹配。
如果栈不为空,使用char top = STTop(&st);获取栈顶元素(最近的未匹配左括号),然后用STPop(&st);弹出它。接下来,检查栈顶元素是否与当前的右括号匹配。如果不匹配,销毁栈并返回false。

 else{if(STEmpty(&st)){return false;// 如果栈为空,则说明没有相匹配的左括号,返回falseSTDestroy(&st);}char top = STTop(&st);// 获取栈顶元素STPop(&st); // 弹出栈顶元素if((*s == '}' && top!= '{') ||(*s == ']' && top!= '[') ||(*s == ')' && top!= '(') ){return false;// 如果栈顶元素与当前右括号不匹配,返回falseSTDestroy(&st);          }}s++;// 移动到下一个字符

字符串遍历完成:

当遍历完整个字符串后,使用bool ret = STEmpty(&st);检查栈是否为空。
如果栈为空,返回true,表示所有的括号都已正确匹配。
如果栈不为空,表示有未匹配的左括号,返回false。

 bool ret = STEmpty(&st);// 检查栈是否为空,即所有括号是否都已匹配

使用STDestroy(&st);销毁栈,释放资源。

在返回最终结果之前,销毁栈以释放分配的资源。

STDestroy(&st); // 销毁栈

这个方法的关键在于利用栈的特性——后进先出(LIFO)——确保我们总是检查最近的未匹配左括号与当前右括号是否匹配。这种方式能有效地处理所有嵌套和顺序相关的括号匹配问题。

以下是栈的实现:

typedef int STDataType;
typedef struct Stack
{STDataType* a;STDataType top; STDataType capacity;
}ST;void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst,STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);// 初始化栈
void STInit(ST* pst)
{assert(pst);pst->a = NULL;       // 初始时,数组指针为空pst->top = 0;        // 栈顶指针初始为0,表示栈为空pst->capacity = 0;   // 初始容量为0
}// 销毁栈
void STDestroy(ST* pst)
{assert(pst);free(pst->a);        // 释放栈内部的数组空间pst->a = NULL;       // 将数组指针置为空pst->top = 0;        // 栈顶指针重置为0pst->capacity = 0;   // 容量重置为0
}// 检查并扩展栈的容量
void SLCheckCapacity(ST* pst)
{assert(pst);if (pst->top == pst->capacity){int newCapacity = (pst->capacity == 0) ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(1); // 如果内存分配失败,则退出程序}pst->a = tmp;pst->capacity = newCapacity;}
}// 向栈中推入一个元素
void STPush(ST* pst, STDataType x)
{assert(pst);SLCheckCapacity(pst); // 检查并扩展容量pst->a[pst->top] = x; // 存放元素pst->top++;           // 栈顶指针增加
}// 从栈中弹出一个元素
void STPop(ST* pst)
{assert(pst);assert(pst->top > 0); // 确保栈不为空pst->top--;           // 栈顶指针减少
}// 获取栈顶元素
STDataType STTop(ST* pst)
{assert(pst);assert(pst->top > 0); // 确保栈不为空return pst->a[pst->top - 1]; // 返回栈顶元素
}// 检查栈是否为空
bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0; // 如果栈顶指针为0,则栈为空
}// 获取栈的大小
int STSize(ST* pst)
{assert(pst);return pst->top; // 返回栈顶指针的位置,即栈的大小
}

以下是本题的实现:

bool isValid(char* s) {ST st;STInit(&st);// 初始化栈while(*s)// 遍历字符串{if(*s == '{' || *s == '[' || *s =='('){STPush(&st,*s);// 如果是左括号,压入栈}else{if(STEmpty(&st)){return false;// 如果栈为空,则说明没有相匹配的左括号,返回falseSTDestroy(&st);}char top = STTop(&st);// 获取栈顶元素STPop(&st); // 弹出栈顶元素if((*s == '}' && top!= '{') ||(*s == ']' && top!= '[') ||(*s == ')' && top!= '(') ){return false;// 如果栈顶元素与当前右括号不匹配,返回falseSTDestroy(&st);          }}s++;// 移动到下一个字符}bool ret = STEmpty(&st);// 检查栈是否为空,即所有括号是否都已匹配STDestroy(&st); // 销毁栈return ret;}

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

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

相关文章

使用 SpringSecurity 发送POST请求出现 403

问题场景 在使用 SpringSecurity 时对一些访问权限进行了设置, 在用户请求资源时出现了403错误 , 通过检查代码发现请求权限是开放的, 并且切换成 GET 请求也是可以通过, 换成POST 请求就无法通过。 解决方法 在 SpringSecurity 中关闭 CSRF 因为 前端向后台发送 post 请求…

Flink Watermark和时间语义

Flink 中的时间语义 时间语义: EventTime:事件创建时间;Ingestion Time:数据进入Flink的时间;Processing Time:执行操作算子的本地系统时间,与机器无关。不同的时间语义有不同的应用场合&#x…

华为端口隔离高级用法经典案例

最终效果: pc4不能ping通pc5,pc5能ping通pc4 pc1不能和pc2、pc3通,但pc2和pc3能互通 vlan batch 2 interface Vlanif1 ip address 10.0.0.254 255.255.255.0 interface Vlanif2 ip address 192.168.2.1 255.255.255.0 interface MEth0/0/1 i…

QT上位机开发(串口界面设计)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 如果上位机要和嵌入式设备进行打交道的话,那么串口可能就是我们遇到的第一个硬件设备。串口的物理接线很简单,基本上就是收…

使用Tensorboard可视化网络结构(基于pytorch)

前言 我们在搭建网络模型的时候,通常希望可以对自己搭建好的网络模型有一个比较好的直观感受,从而更好地了解网络模型的结构,Tensorboard工具的使用就给我们提供了方便的途径 Tensorboard概况 Tensorboard是由Google公司开源的一款可视化工…

【langchain】入门初探实战笔记(Chain, Retrieve, Memory, Agent)

1. 简介 1.1 大语言模型技术栈 大语言模型技术栈由四个主要部分组成: 数据预处理流程(data preprocessing pipeline)嵌入端点(embeddings endpoint )向量存储(vector store)LLM 终端&#xff…

机器学习(四) -- 模型评估(1)

系列文章目录 机器学习(一) -- 概述 机器学习(二) -- 数据预处理(1-3) 机器学习(三) -- 特征工程(1-2) 机器学习(四) -- 模型评估…

GaussDB数据库使用COPY命令导数

目录 一、前言 二、GaussDB数据库使用COPY命令导数语法 1、语法COPY FROM 2、语法COPY TO 3、特别说明及参数示意 三、GaussDB数据库使用COPY命令导数示例 1、操作步骤 2、准备工作(示例) 3、把一个表的数据拷贝到一个文件(示例&…

【python入门】day17:模块化编程、math库常见函数

什么叫模块 模块的导入 导入所有:import 模块名称 导入指定:from 模块名称 import 函数/变量/类 python的math库 什么是math库 Python的math库是Python的内建库之一,它提供了许多数学函数,包括三角函数、对数函数、幂函数等&a…

生成式AI在自动化新时代中重塑RPA

生成式AI的兴起正在推动行业的深刻变革,其与RPA技术的结合,标志着自动化领域新时代的到来。这种创新性结合极大地提升了系统的适应性,同时也推动了高级自动化解决方案的发展,为下一代RPA的诞生奠定了坚实的基础。 核心RPA技术专注…

Intel SGX -- The Life Cycle of an SGX Enclave

文章目录 前言一、The Life Cycle of an SGX Enclave1.1 Creation1.2 Loading1.3 Initialization1.4 Teardown 二、The Life Cycle of an SGX Thread2.1 Synchronous Enclave Entry2.2 Synchronous Enclave Exit2.3 Asynchronous Enclave Exit (AEX)2.4 Recovering from an Asy…

一个基于SpringBoot+Thymeleaf渲染的图书管理系统

功能: 用户: a.预约图书 b.查看预约记录 c.还书 管理员: a.添加图书 b.处理预约(借书) c.查看借阅记录 另: 1.当用户过了还书日期仍旧未还书时会发邮件通知 2.当有书被还时发邮件通知预约书的用户到图书馆进行借书