括号匹配(使用链栈实现)

news2024/11/24 4:47:49

目录

  • 0. 前言
  • 1. 括号匹配——题目描述
  • 2. 解题思路
  • 3. 括号匹配意义

0. 前言

数据结构——括号匹配(使用链栈实现)

操作系统:Windows10 家庭版

开发环境:Dev-Cpp

1. 括号匹配——题目描述

给定一个只包含括号的字符串s,判断这个字符串中的括号是否匹配。如果匹配,返回true;否则返回false。

例如,对于字符串s = “(()())”,括号是匹配的。对于字符串s = “()())”,则括号是不匹配的。

题目意思很简单,就是看看括号是否成对出现。

现在我们来给自己加大难度,不仅算小括号,把大括号中括号小括号全部算上。

2. 解题思路

可以用栈来解决。具体思路如下:

  • 创建一个栈stack,遍历字符串s中的每个字符char。
  • 如果char是左括号,将其压入栈stack中。
  • 如果char是右括号,弹出栈顶的字符,并判断是否匹配。
  • 如果与栈顶字符匹配,则继续遍历下一个字符。
  • 如果不匹配,则括号不匹配,返回false。
  • 如果遍历完整个字符串s后栈stack为空,则括号匹配,返回true;否则括号不匹配,返回false。

接下来看我的代码实现:

#include<iostream>
#include<malloc.h>
#include<string.h>
 
using namespace std;
 
typedef int ElemType;
 
typedef struct LinkNode {
	ElemType data;
	struct LinkNode* next;
}*LiStack,LinkNode;
 
 
bool InitStack(LiStack& S);
bool StackEmpty(LiStack S);
bool Push(LiStack& S, ElemType x);
bool Pop(LiStack& S, ElemType& x);
bool GetTop(LiStack S, ElemType& x);
bool DestoryStack(LiStack& S);
 
bool InitStack(LiStack& S) {
	S = (LiStack)malloc(sizeof(LinkNode));
	if (S == NULL) return false;
	S->next = NULL;
	return true;
}
 
bool StackEmpty(LiStack S) {
	if (S->next == NULL) return true;
	return false;
}
 
bool Push(LiStack& S, ElemType x) {
	LinkNode* p;
	p = (LinkNode*)malloc(sizeof(LinkNode));
	if (p == NULL) return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}
 
bool Pop(LiStack& S, ElemType& x) {
	if (StackEmpty(S)) return false;
	LinkNode* p = S->next;
	S->next = p->next;
	x = p->data;
	free(p);
	return true;
}
 
bool GetTop(LiStack S, ElemType& x) {
	if (StackEmpty(S)) return false;
	x = S->next->data;
	return true;
}
 
bool DestoryStack(LiStack& S) {
	while (S->next != NULL) {
		LinkNode* p = S->next;
		S->next = p->next;
		free(p);
	}
	free(S);
	return true;
}
 
void test() {
 
	LiStack S;
	InitStack(S);
	for (int i = 0; i <= 5; i++) {
		Push(S, i);
	}
	ElemType x;
	GetTop(S, x);
	cout << x << endl;
	while (!StackEmpty(S)) {
		Pop(S, x);
		cout << x << endl;
	}
}
 
int main() {
	
	//初始化堆栈	
	LiStack s;
	printf("堆栈指针初始化前的地址是:%p\n",s);
	InitStack(s);
	printf("堆栈指针初始化后的地址是:%p\n",s);
	
	char left[] = "{[(";
	char right[] = "}])"; 
	int flah;
	
	
	//输入 
	char str[20];
	printf("请输入一个含括号的字符串:");
	scanf("%s",str);

	
	int i,j,k;
	for(i=0;i<strlen(str);i++)
	{
		for(j=0;j<3;j++)
		{
			//检查到为左括号则入栈 
			if(str[i] == left[j])
			{
				Push(s,str[i]);
			}
			
			//检查到为右括号则进行检查 
			else if(str[i] == right[j])
			{
				//栈空还是匹配到右括号说明不匹配,直接退出 
				if (StackEmpty(s))
				{
					printf("右括号数大于左括号!\n");
					exit(0);
				}
				ElemType temp_s;
				Pop(s,temp_s);
				
				//查找右括号对应左括号的位号 
				for (k=0;k<3;k++)
				{
					if (temp_s == left[k])
					break;
				} 
				
				//匹配则输出,不匹配则退出 
				if (right[k] == str[i])
				printf("%c%c\n",temp_s,str[i]);
				else{
					printf("error!\n");
					exit(0);
				}
			}
			//其他字符则继续执行循环 
			else continue;
		}
	}
	
	//能够在上面三重循环中不 exit(0) 说明括号都匹配上了
	
	
	if (StackEmpty(s))
		printf("匹配成功\n");
	else 
		printf("匹配失败\n");
		
	//执行完毕释放堆栈内存 
	free(s); 

	return 0;
}

在这里插入图片描述
匹配成功!

3. 括号匹配意义

括号匹配是一种常用的算法技巧,主要用于验证括号是否成对出现、嵌套是否合法等等。

在编程中,括号匹配常用于编写高级语言的编译器、解析器等程序。在这些程序中,括号匹配常用于检查代码中括号的嵌套是否正确,因为括号的嵌套错误常常会导致程序编译或解析出错。

此外,在日常生活中,括号匹配也有很多实际应用。比如,医生为患者开具处方时,需要将药品名和用量用括号括起来,如果括号匹配错误,会导致药方不清晰,给患者带来风险。再比如,在数学公式中,括号的正确使用也是非常重要的,因为括号的错误使用可能会导致公式结果出错。

因此,括号匹配可以帮助我们在编程和生活中减少错误,提高工作效率和生活质量。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【图】单源最短路径

最短路径 图上的最短路径&#xff1a;两顶点之间经过的边数最少的路径&#xff1b; 网上的最短路径&#xff1a;两顶点之间经过的边上权值之和最少的路径&#xff08;源点->终点&#xff09;。 a星算法、迪杰斯特拉算法、佛洛依德算法。 迪杰斯特拉算法 单源最短路径按…

SpringBoot项目登录并接入MFA二次认证

MFA多因素认证(Multi-Factor Authentication )&#xff1a; 一些需要身份认证的服务&#xff08;如网站&#xff09;&#xff0c;为了提升安全性&#xff0c;通常会在账号密码登录成功后&#xff0c;要求用户进行第二种身份认证&#xff0c;以确保是正确用户登录&#xff0c;避…

【C语言】C预处理器(宏、文件包含、条件编译...)

一、C语言编译的预处理阶段1.1 C语言的编译过程1.2 C语言编译的预处理 二、C语言 宏2.1替换常量2.2函数宏2.3 字符串化和连接&#xff1a;#和##2.4 变参宏 三、文件包含&#xff1a;#include3.1 写法3.2 头文件的作用——声明3.3 头文件和extern 、static 四、 其他指令4.1 #un…

Ansible基础4——变量、机密、事实

文章目录 一、变量二、机密2.1 创建加密文件2.2 查看加密文件2.3 编辑加密文件内容2.4 加密现有文件2.5 解密文件2.6 更改加密密码 三、事实3.1 收集展示事实3.2 展示某个结果3.3 新旧事实命令3.4 关闭事实3.5 魔法变量 一、变量 常设置的变量&#xff1a; 要创建的用户要安装的…

【C++ 基础篇:19】:类的构造函数与初始化列表:用法说明及构造函数的细节内容补充!

本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大特性等&#…

Kubernetes_容器网络_循序渐进地学习kubernetes网络

文章目录 前言一、Linux网络命名空间1.1 linux网络命名空间1.2 不同网络命名空间的通信两个网络命名空间通信多个网络命名空间通信 二、K8S Pod网络通信2.1 Pod内部容器的网络通信2.2 相同node: 不同pod间的网络通信2.3 不同node: 不同pod间的网络通信2.4 容器网络插件: Flanne…

C++STL库之map

文章目录 关于仿函数stackdeque&#xff08;双端对列&#xff09;queuepriority_queuemap(重点)set(去重) 关于仿函数 //C不能重载的运算符sizeof、 ::、 ? :、 .、 *、 class Add { public:int operator()(int a, int b)const{return a b;} }; //函数对象&#xff0c;仿函数…

EDA数字钟(三)

文章目录 前言一、设计内容二、模块结构三、代码编写1、顶层模块Digclk2、状态控制模块Ctrl3、按键消抖模块Filter4、计时模块Time5、闹钟模块Alarm6、显示模块Display7、数码管驱动模块Smg 四、测试文件五、波形仿真总结 前言 再次编写数字钟Verilog程序&#xff0c;使其符合…

数据迁移工具,用这8种就够了

前言 最近由于工作需要需要进行数据迁移&#xff0c;那么ETL数据迁移工具该用哪些呢&#xff1f; ETL(是Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程)&#xff0c;对于企业应用来说&#xff0c;我们经常会遇到各种数据的处理、转换、迁移的场景。…

50 Projects 50 Days - Split Landing Page 学习记录

项目地址 Split Landing Page 展示效果 Split Landing Page 实现思路 当鼠标移动到左右两块区域时&#xff0c;分别给容器添加不同的class实现样式的变换。 有两种思路可以实现&#xff0c;一种是hover时改变宽度&#xff0c;一种是hover时改变flex拉伸比例&#xff0c;两…

从零手写操作系统之RVOS外设中断实现-04

从零手写操作系统之RVOS外设中断实现-04 RISC-V 中断&#xff08;Interrupt&#xff09;的分类RISC-V Trap &#xff08;中断&#xff09;处理中涉及的寄存器寄存器 mie、mip中断处理流程PLIC 介绍外部中断&#xff08;external interrupt &#xff09;PLICPLIC Interrupt Sour…

精调万分(Fine tune SAM)-万分预测器的解读和精调之一

缘起 分割万物(segment-anything model, SAM, 万分), 是图像分割领域的革命, 图像分割从此进入大模型时代. 如何自定义这个大模型以为己用? 或者说, 通过精调取长补短用于自己的项目?这是一个值得研究的问题, 在这里我试着探索一下, 万分在医学影像学里面的脊柱分割的应用. …

【sentinel】滑动时间窗口算法在Sentinel中的应用

固定窗口算法&#xff08;计数器法&#xff09; 算法介绍 计数器法是限流算法里最简单也是最容易实现的一种算法。比如我们规定&#xff0c;对于A接口来说&#xff0c;我们1秒的访问次数不能超过10次。那么我们可以这么做&#xff1a;在一开始的时候&#xff0c;我们可以设置…

ESP-BOX官方例程实践

1.下载esp-box项目代码 github仓库&#xff1a;https://github.com/espressif/esp-box gitee仓库&#xff1a;https://gitee.com/EspressifSystems/esp-box 使用git工具和如下命令进行下载&#xff1a; git clone --recursive https://github.com/espressif/esp-box.git or gi…

【C++ 基础篇:21】:friend 友元四连问:什么是友元?友元类?友元函数?什么时候用友元?

本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大特性等&#…

S7-200 PLC的CPU模块介绍

更多关于西门子S7-200PLC内容查看&#xff1a;西门子200系列PLC学习课程大纲(课程筹备中) 1.什么是西门子200PLC的CPU? 如下图1-1所示&#xff0c;S7-200 PLC CUP是将一个微处理器&#xff0c;一个集成电源&#xff0c;一定的数字量或模拟量I/O&#xff0c;一定的通信接口等…

【Linux】—— git的管理以及使用

前言&#xff1a; 在上篇我们已经学习了关于调试器gdb的相关知识&#xff0c;本期我将为大家介绍的是关于版本控制工具——git的使用教程&#xff01;&#xff01;&#xff01; 目录 前言 &#xff08;一&#xff09;git的历史介绍 &#xff08;二&#xff09;github和gite…

Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务

今天儿童节&#xff0c;犬子已经9个多月了&#xff0c;今天是他的第一个儿童节。中年得子&#xff0c;其乐无穷&#xff08;音&#xff1a;ku bu kan yan&#xff09;…回头是岸啊 〇、 示例效果 一连创建5个异步任务[id 从0~4]&#xff0c;先停止其中的第id 4的任务&#x…

Flutter进阶篇-布局(Layout)原理

1、约束、尺寸、位置 overrideWidget build(BuildContext context) {return Scaffold(body: LayoutBuilder(builder: (context, constraints) {print("body约束:" constraints.toString());return Container(color: Colors.black,width: 300,height: 300,child: L…

【企业化架构部署】基于Nginx搭建LNMP架构

文章目录 一、安装 MySQL 数据库1. 安装Mysql环境依赖包2. 创建运行用户3. 编译安装4. 修改mysql 配置文件5. 更改mysql安装目录和配置文件的属主属组6. 设置路径环境变量7. 初始化数据库8. 添加mysqld系统服务9. 修改mysql 的登录密码10. 授权远程登录 二、编译安装 nginx 服务…