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

栈在括号匹配中的应用(栈/链栈 纯C实现)

目录

1 问题背景

2 具体思路

3 代码实现

3.1 顺序栈实现

3.2 链栈实现


1 问题背景

  栈的括号匹配问题是指在给定一个字符串(包含多种括号),判断其中的括号是否能够正确匹配,即每个左括号是否有一个对应的右括号与之匹配,并且左右括号必须以正确的顺序进行匹配。

例如,字符串"((()))"中的括号就能够正确匹配,而字符串"()())"中的括号就无法正确匹配。

 

2 具体思路

这是王道给出的流程图:

图1 王道给出的流程图

 

看起来有点吃力,我来总结一下,很简单,就几步:

  1. 遍历给定的字符串,对于每个字符进行判断。
  2. 如果字符是左括号,将其入栈。
  3. 如果字符是右括号,将其与栈顶元素作比较,判断该元素是否是与之匹配的左括号。如果是,弹出栈顶元素,并继续遍历;如果不是,说明括号不匹配,返回false。
  4. 如果字符串遍历完毕,栈为空,则说明全部括号匹配,返回true;否则,返回false。

注意如果在准备弹出元素时发现栈已为空,说明前面没有左括号与该右括号匹配,返回false。

3 代码实现

以Acwing上一道例题举例:3693. 括号匹配 - AcWing题库

输入格式

共一行,包含一个由 `<`,`(`,`{`,`[`,`>`,`)`,`}`,`]` 构成的字符串。

输出格式

如果输入的字符串中的括号正确匹配则输出 `yes`,否则输出 `no`。

数据范围

输入字符串长度不超过 10000。

输入样例:

    (){}

输出样例:

    yes

 

3.1 顺序栈实现

#include<stdio.h>
#include<string.h>
#include<stdbool.h>    //C语言引入该库才有bool值#define MAX_SIZE 100000  //定义栈中元素的最大个数typedef struct {int data[MAX_SIZE];  //静态数组存放栈中元素int top;    //栈顶指针
} SqStack;//初始化栈
void initStack(SqStack *s) {s->top = -1;
}//判断栈空
bool stackEmpty(SqStack s) {return s.top == -1;  //如果栈是空的,那么就会返回true
}//新元素入栈
bool push(SqStack *s, int x) {if (s->top == MAX_SIZE - 1) //如果栈已满,返回falsereturn false;s->data[++(s->top)] = x;  //否则先将栈顶指针的值加1,然后再使用增加后的栈顶指针指向的位置作为数组下标,将x存储到data数组中return true;
}//出栈
bool pop(SqStack *s, int *x) {if (s->top == -1) { //因为栈已空,再出栈报错返回falsereturn false;}*x = s->data[s->top--]; //从栈顶取出一个元素并赋值给x*,然后将栈顶指针减1,即把栈顶指针指向它下方的元素/*为什么给x*呢?因为需要通过指针参数才能把栈的元素值传递出去,进而传给topElem*/return true;
}//括号匹配算法的主体
bool bracketCheck(char str[]) {SqStack s;    initStack(&s);for (int i = 0; i < strlen(str); i++) {if (str[i] == '<' || str[i] == '(' || str[i] == '{' || str[i] == '[') {push(&s, str[i]);} else {if (stackEmpty(s)) {return false;}int topElem;  //topElem作为中间变量,记录从栈中弹出的栈顶元素if (!pop(&s, &topElem)) { //如果取出栈顶元素失败,说明栈为空,则匹配失败,返回falsereturn false;}if (str[i] == '>' && topElem != '<') {return false;}if (str[i] == ')' && topElem != '(') {return false;}if (str[i] == ']' && topElem != '[') {return false;}if (str[i] == '}' && topElem != '{') {return false;}}}return stackEmpty(s); //栈空,说明所有括号都能匹配成功,返回true;否则说明还有没配成功的括号,返回false
}int main() {char str[MAX_SIZE];  //接收字符串scanf("%s", str);if (bracketCheck(str)) printf("yes");else printf("no");return 0;
}

3.2 链栈实现

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* next;
} Node;typedef struct {Node* top;int count;
} LinkedStack;// 初始化链栈
void InitStack(LinkedStack* S) {S->top = NULL;S->count = 0;
}// 判断栈空
bool StackEmpty(LinkedStack* S) {return S->count == 0;
}// 新元素入栈
bool Push(LinkedStack* S, int x) {Node* node = (Node*)malloc(sizeof(Node));if (node == NULL) {return false;  // 内存分配失败,入栈失败}node->data = x;node->next = S->top;S->top = node;S->count++;return true;
}// 弹出栈顶元素
bool Pop(LinkedStack* S, int* x) {if (StackEmpty(S)) {return false;  // 栈空,弹出失败}Node* node = S->top;S->top = node->next;*x = node->data;free(node);S->count--;return true;
}// 读取栈顶元素
bool GetTop(LinkedStack* S, int* x) {if (StackEmpty(S)) {return false;  // 栈空,读取失败}*x = S->top->data;return true;
}// 括号匹配检查
bool bracketCheck(char str[]) {LinkedStack S;InitStack(&S);for (int i = 0; i < strlen(str); i++) {if (str[i] == '<' || str[i] == '(' || str[i] == '{' || str[i] == '[') {Push(&S, str[i]);} else {if (StackEmpty(&S)) {return false;  // 栈空,匹配失败}int topElem;if (!Pop(&S, &topElem)) {return false;  // 弹出失败,匹配失败}if (str[i] == '>' && topElem != '<') {return false;  // 匹配失败}if (str[i] == ')' && topElem != '(') {return false;  // 匹配失败}if (str[i] == ']' && topElem != '[') {return false;  // 匹配失败}if (str[i] == '}' && topElem != '{') {return false;  // 匹配失败}}}return StackEmpty(&S);
}int main() {char str[100000];scanf("%s", str);if (bracketCheck(str)) {printf("yes\n");} else {printf("no\n");}return 0;
}

 

相关文章:

栈在括号匹配中的应用(栈/链栈 纯C实现)

目录 1 问题背景 2 具体思路 3 代码实现 3.1 顺序栈实现 3.2 链栈实现 1 问题背景 栈的括号匹配问题是指在给定一个字符串&#xff08;包含多种括号&#xff09;&#xff0c;判断其中的括号是否能够正确匹配&#xff0c;即每个左括号是否有一个对应的右括号与之匹配&#x…...

C语言Switch语句用法

C switch 语句 一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case&#xff0c;且被测试的变量会对每个 switch case 进行检查。 语法 C 语言中 switch 语句的语法&#xff1a; switch(expression){case constant-expression :statement(s);break;…...

Curl编码请求参数,API接口请求示例参数

请求参数请求参数&#xff1a;num_iid610947572360 参数说明&#xff1a;num_iid:1688商品ID sales_data:&sales_data1 获取近30天成交数据 agent:&agent1 获取1688分销代发价格数据请求示例 测试入口 Curl PHP PHPsdk JAVA C# Python-- 请求示例 url 默认请求参数已经…...

【C/C++】类型限定符extern、const、Volatile、register

1、extern&#xff1a; 声明一个变量&#xff0c;extern声明的变量没有建立存储空间。 extern int a ; //变量在定义的时候创建存储空间。 ①当我们在编译器中试图运行以下代码&#xff0c;系统会报错。 错误原因是“无法解析外部符号_a”.系统认为变量a是没有开辟内存空间的…...

day54【代码随想录】二刷数组

文章目录前言一、二分查找&#xff08;力扣724&#xff09;二、移除元素&#xff08;力扣27&#xff09;【双指针】三、有序数组的平方&#xff08;力扣977&#xff09;【双指针】四、合并两个有序数组&#xff08;力扣88&#xff09;五、长度最小的子数组&#xff08;力扣209&…...

哪个品牌蓝牙耳机性价比高?性价比高的平价蓝牙耳机推荐

现如今&#xff0c;随着蓝牙技术的进步&#xff0c;蓝牙耳机在人们日常生活中的便捷性更胜从前。越来越多的蓝牙耳机品牌被大众看见、认可。那么&#xff0c;哪个品牌的蓝牙耳机性价比高&#xff1f;接下来&#xff0c;我给大家推荐几款性价比高的平价蓝牙耳机&#xff0c;一起…...

揭秘关于TFRcord的五脏六腑

揭秘关于TFRcord的五脏六腑 前言&#xff1a;本篇文章将演示如何创建、解析和使用tf.Example消息&#xff0c;以及如何在.tfrecord文件之间对tf.Example消息进行序列化、写入和读取。 教程讲解使用的都是结构化数据&#xff0c;文章最后还会演示如果将图片写成.tfrecord文件&am…...

【Shell学习笔记】3.Shell 传递参数及数组

前言 本章介绍Shell的传递参数和数组。 Shell 传递参数 我们可以在执行 Shell 脚本时&#xff0c;向脚本传递参数&#xff0c;脚本内获取参数的格式为&#xff1a;$n。n 代表一个数字&#xff0c;1 为执行脚本的第一个参数&#xff0c;2 为执行脚本的第二个参数&#xff0c;…...

【终结Bug】ModuleNotFoundError: No module named ‘cv2’

解决方案&#xff1a; 打开 cmd键入 pip install opencv_python -i https://pypi.tuna.tsinghua.edu.cn/simple...

SQL Server2008详细安装步骤(保姆式教程)

安装包下载 链接&#xff1a;https://pan.baidu.com/s/1Rjx4DHJBeCW2asC_4Kzo6Q?pwdchui 提取码&#xff1a;chui 安装过程 1.解压后使用管理员身份打开安装程序 2.选择全新安装或向现有安装添加新功能 3.确认 4.输入产品密钥&#xff08;上方网盘安装包里有&#xff0…...

Linux常用操作

Linux常用操作 前言常用命令&#xff1a;一些操作命令&#xff1a;前言 本文是笔者在使用cadence的过程中&#xff0c;操作linux的笔记&#xff0c;仅记录个人常用&#xff0c;持续更新 常用命令&#xff1a; &#xff08;1&#xff09;高频&#xff1a;会了这几个就能在文件…...

Golang 处理parquet文件实战教程

Parquet是Apache基金会支持的项目&#xff0c;是面向列存储二进制文件格式。支持不同类型的压缩方式&#xff0c;广泛用于数据科学和大数据环境&#xff0c;如Hadoop生态。 本文主要介绍Go如何生成和处理parquet文件。 创建结构体 首先创建struct&#xff0c;用于表示要处理…...

腾讯TIM实现即时通信 v3+ts实践

目录 初始化sdk 功能描述 初始化 准备 SDKAppID 调用初始化接口 监听事件 发送消息 创建消息 创建文本消息 登录登出 功能描述 登录 登出 销毁 登录设置 获取会话列表 功能描述 获取会话列表 获取全量的会话列表 历史消息 功能描述 拉取消息列表 分页拉取…...

华为OD机试 - 回文字符串(Java JS Python)

题目描述 如果一个字符串正读和反渎都一样(大小写敏感),则称它为一个「回文串」,例如: leVel是一个「回文串」,因为它的正读和反读都是leVel;同理a也是「回文串」art不是一个「回文串」,因为它的反读tra与正读不同Level不是一个「回文串」,因为它的反读leveL与正读不…...

APP测试的7大注意点。

1. 运行 1&#xff09; App安装完成后的试运行&#xff0c;可正常打开软件。 2&#xff09; App打开测试&#xff0c;是否有加载状态进度提示。 3&#xff09; App⻚面间的切换是否流畅&#xff0c;逻辑是否正确。 4&#xff09; 注册 同表单编辑⻚面 用户名密码⻓度 …...

设计模式-第4章(装饰模式)

装饰模式装饰模型装饰模式示例商场收银程序&#xff08;简单工厂策略装饰模式实现&#xff09;装饰模式总结装饰模型 装饰模式&#xff08;Decorator&#xff09;&#xff0c;动态地给一个对象添加一些额外的职责&#xff0c;就增加功能来说&#xff0c;装饰模式比生成子类更为…...

【算法设计-分治】快速幂与龟速乘

文章目录1. 快速幂2. 龟速乘3. 快速幂取模4. 龟速乘取模5. 快速幂取模优化1. 快速幂 算法原理&#xff1a; 计算 311&#xff1a; 311 (35)2 x 335 (32)2 x 332 3 x 3仅需计算 3 次&#xff0c;而非 11 次 计算 310&#xff1a; 310 (35)235 (32)2 x 332 3 x 3仅需计算…...

基于新一代kaldi项目的语音识别应用实例

本文是由郭理勇在第二届SH语音技术研讨会和第七届Kaldi技术交流会上对新一代kaldi项目在学术及“部署”两个方面报告的内容上的整理。如果有误&#xff0c;欢迎指正。 文字整理丨李泱泽 编辑丨语音小管家 喜报&#xff1a;新一代Kaldi团队三篇论文均被语音顶会ICASSP-2023接…...

【GO】31.grpc 客户端负载均衡源码分析

这篇文章是记录自己查看客户端grpc负载均衡源码的过程&#xff0c;并没有太详细的讲解&#xff0c;参考价值不大&#xff0c;可以直接跳过&#xff0c;主要给自己看的。一.主要接口&#xff1a;Balancer Resolver1.Balancer定义Resolver定义具体位置为1.grpc源码对解析器(resol…...

PTA L1-058 6翻了(详解)

前言&#xff1a;内容包括&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 题目&#xff1a; “666”是一种网络用语&#xff0c;大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”&#xff0c;意思是“6翻了”&#xff0…...

HunyuanVideo-Foley音效生成:支持SMPTE时间码对齐视频关键帧

HunyuanVideo-Foley音效生成&#xff1a;支持SMPTE时间码对齐视频关键帧 1. 产品概述 HunyuanVideo-Foley是一款专为影视后期制作设计的AI音效生成工具&#xff0c;其核心创新在于支持SMPTE时间码精确对齐视频关键帧。这意味着音效师可以基于视频时间轴上的特定帧&#xff0c…...

KKManager全流程管理指南:从安装到效率提升

KKManager全流程管理指南&#xff1a;从安装到效率提升 【免费下载链接】KKManager Mod, plugin and card manager for games by Illusion that use BepInEx 项目地址: https://gitcode.com/gh_mirrors/kk/KKManager 学习目标 理解KKManager的核心价值与应用场景掌握从…...

Spring Boot 3.0 + Vue 3 实战:手把手教你搭建图书管理系统(附完整源码)

Spring Boot 3.0 Vue 3 全栈实战&#xff1a;现代化图书管理系统开发指南 在当今快速发展的互联网时代&#xff0c;掌握前后端分离开发技术已成为中级开发者必备的核心竞争力。本文将带你从零开始&#xff0c;使用Spring Boot 3.0和Vue 3这两个当下最热门的技术栈&#xff0c;…...

物联网水产养殖监控系统:智能联动,实现养殖设备自动调控

一、应用背景 水产养殖是我国农业经济的重要组成部分&#xff0c;传统养殖模式长期依赖人工巡检、经验判断&#xff0c;存在诸多难以破解的行业痛点&#xff0c;严重制约养殖效益与产业可持续发展。随着物联网、大数据、边缘计算、无线通信技术的成熟&#xff0c;搭建智能化、数…...

Rock3A开发板实战:OpenBMC移植全记录(附避坑指南)

Rock3A开发板OpenBMC移植实战&#xff1a;从硬件适配到性能调优 当RK3568处理器遇上OpenBMC&#xff0c;会碰撞出怎样的火花&#xff1f;作为瑞芯微旗下性能与功耗平衡的明星芯片&#xff0c;RK3568在边缘计算领域已证明其价值。而将其应用于BMC&#xff08;基板管理控制器&…...

还在纸上谈Agent?来搓一只你的「腾讯小龙虾」

大模型卷完参数&#xff0c;开始卷落地。当所有人还在谈论AI Agent如何颠覆未来工作方式时&#xff0c;一部分开发者已经让它为自己“打工”了。从写一封邮件&#xff0c;到整理一份报告&#xff0c;再到串联多个系统完成业务动作&#xff0c;AI 正在完成一次关键的身份跃迁&am…...

手把手教你用两块STM32F103C8T6实现CAN总线点对点通信(附完整代码)

从零开始实现STM32F103C8T6双板CAN总线通信实战指南 在嵌入式开发领域&#xff0c;CAN总线因其高可靠性和实时性成为工业控制、汽车电子等场景的首选通信协议。对于初学者而言&#xff0c;使用两块STM32F103C8T6开发板搭建CAN通信系统是掌握该技术的经典入门项目。本文将彻底拆…...

嵌入式开发调试与问题诊断实战指南

嵌入式工程师常见问题诊断与调试经验分享1. 典型开发场景分析1.1 开发环境差异问题"在我的开发环境运行正常"是嵌入式工程师最常遇到的困境之一。这种现象通常源于&#xff1a;编译器版本差异&#xff08;GCC/Keil/IAR版本不一致&#xff09;硬件平台差异&#xff08…...

Onekey:Steam游戏清单管理的自动化解决方案 | 玩家与开发者必备工具

Onekey&#xff1a;Steam游戏清单管理的自动化解决方案 | 玩家与开发者必备工具 【免费下载链接】Onekey Onekey Steam Depot Manifest Downloader 项目地址: https://gitcode.com/gh_mirrors/one/Onekey 当独立游戏开发者小林第三次因为手动复制Steam App ID出错而导致…...

springboot基于Vue的大学生心理健康交流系统的设计与实现

目录系统架构设计数据库设计核心功能模块前端界面开发测试部署方案项目进度规划注意事项项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作系统架构设计 采用前后端分离架构&#xff0c;后端使用SpringBoot框架提供RESTful API接…...