当前位置: 首页 > news >正文

C语言编程--17.有效的括号

题目:

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

示例 1
输入:s = “()”
输出:true

示例 2
输入:s = “()[]{}”
输出:true

示例 3
输入:s = “(]”
输出:false

示例 4
输入:s = “([])”
输出:true

提示

1 <= s.length <= 104
s 仅由括号 ‘()[]{}’ 组成

代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>// 定义链表节点结构体
// 每个节点包含一个字符数据和一个指向下一个节点的指针
typedef struct Node
{char data;  // 存储字符数据struct Node *next;  // 指向下一个节点的指针
} Node;// 定义栈结构体
// 栈使用链表实现,top 指针指向栈顶节点
typedef struct
{Node* top;  // 栈顶指针
} Stack;// 初始化栈
// 该函数将栈的 top 指针置为 NULL,表示栈为空
void initStack(Stack* s)
{s->top = NULL;  // 将栈顶指针置为 NULL
}// 判断栈是否为空
// 如果栈的 top 指针为 NULL,则栈为空,返回 1;否则返回 0
int isEmpty(Stack* s)
{return s->top == NULL;  // 判断栈顶指针是否为 NULL
}// 入栈操作
// 该函数将一个字符压入栈中
void push(Stack* s, char value)
{// 为新节点分配内存Node* newnode = (Node*)malloc(sizeof(Node));if (newnode == NULL){// 内存分配失败,输出错误信息printf("内存分配失败!");return;}newnode->data = value;  // 将数据存入新节点newnode->next = s->top;  // 新节点的 next 指针指向原栈顶节点s->top = newnode;  // 更新栈顶指针为新节点
}// 出栈操作
// 该函数将栈顶元素弹出
void pop(Stack* s)
{if (isEmpty(s)){// 栈为空,输出错误信息printf("栈为空");return;}Node* temp = s->top;  // 临时指针指向栈顶节点char value = temp->data;  // 获取栈顶节点的数据s->top = s->top->next;  // 更新栈顶指针为原栈顶节点的下一个节点free(temp);  // 释放原栈顶节点的内存
}// 判断字符串中的括号是否有效
// 该函数使用栈来检查字符串中的括号是否匹配
bool isValid(char* s) {Stack stack;initStack(&stack);  // 初始化栈int n = strlen(s);  // 获取字符串的长度for (int i = 0; i < n; i++){if (s[i] == '(' || s[i] == '{' || s[i] == '[')// 如果是左括号,直接入栈push(&stack, s[i]);else if (s[i] == ')' && stack.top && stack.top->data == '(')// 如果是右括号且栈不为空,并且栈顶元素是对应的左括号,则出栈pop(&stack);else if (s[i] == ']' && stack.top && stack.top->data == '[')// 如果是右括号且栈不为空,并且栈顶元素是对应的左括号,则出栈pop(&stack);else if (s[i] == '}' && stack.top && stack.top->data == '{')// 如果是右括号且栈不为空,并且栈顶元素是对应的左括号,则出栈pop(&stack);else// 其他情况,将字符入栈push(&stack, s[i]);}if (stack.top)// 如果栈不为空,说明有括号不匹配,返回 falsereturn false;else// 如果栈为空,说明所有括号都匹配,返回 truereturn true; 
}

代码分析:

逻辑清晰:代码结构清晰,将栈的基本操作(初始化、入栈、出栈、判断是否为空)封装成独立的函数,提高了代码的可读性和可维护性。isValid 函数利用栈的特性来判断括号是否匹配,逻辑简洁明了。
内存管理:在入栈操作中,会检查内存分配是否成功,避免了因内存分配失败而导致的程序崩溃。在出栈操作中,会释放栈顶节点的内存,避免了内存泄漏。
扩展性:栈的实现使用链表,易于扩展。如果需要存储更多类型的数据,只需要修改 Node 结构体的 data 成员即可。

http://www.xdnf.cn/news/146989.html

相关文章:

  • 氢气泄漏应急预案应包括哪些内容?
  • 【资料推荐】LVDS Owner’s Manual
  • contenthash 持久化缓存
  • MODBUS转ProfiNet边缘计算网关驱动霍尼韦尔HPT温湿度仪表的动态控制闭环方案
  • Shell、Bash 执行方式及./ 执行对比详解
  • 网络通信的字节序
  • Postman-win64-7.2.2 安装教程(Windows 64位详细步骤)
  • API性能瓶颈分析与优化方法
  • QQ音乐安卓版歌曲版权覆盖范围与曲库完整度评测
  • Kubernet查找pods不断重启原因
  • 【Nova UI】十、打造组件库第一个组件-图标组件(下):从.svg 到 SVG Vue 组件的高效蜕变✨
  • gerbera文件转PCB文件-Altium Designer
  • GitHub 趋势日报 (2025年04月24日)
  • 赛灵思 XCKU115-2FLVB2104I Xilinx Kintex UltraScale FPGA
  • Parasoft C++Test软件单元测试_对函数打桩的详细介绍
  • AKM旭化成微电子全新推出能量收集IC“AP4413系列”
  • 自然语言处理+知识图谱:智能导诊的“大脑”是如何工作的?
  • C++中的vector和list的区别与适用场景
  • LLM Graph Rag(基于LLM的事件图谱RAG)
  • 一种用于加密代理流量检测的轻量级深度学习方法
  • jdk-8u202-linux-x64.tar.gz官方下载地址
  • mysql基础——数据表查询(全面解析)
  • 技术书籍推荐(003)
  • A2A与MCP之间的简单理解
  • 【Echarts】使用echarts绘制多个不同类型的中国地图
  • Redis 集群切片全解析:四种常见技术的原理、优劣与应用
  • Github 2025-04-25 Java开源项目日报 Top8
  • Java实现HTML转PDF(deepSeekAi->html->pdf)
  • 通过模仿学习实现机器人灵巧操作:综述(下)
  • Azure Data Factory ETL设计与调度最佳实践