数据结构(3.8)——栈的应用
栈在括号匹配中的应用
流程图
代码
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 10typedef struct {char data[MaxSize];int top;
} SqStack;// 初始化栈
void InitStack(SqStack* S) {S->top = -1; // 初始化栈顶指针
}// 判空
bool StackEmpty(SqStack* S) {if (S->top == -1) {return true;} else {return false;}
}// 入栈
bool Push(SqStack* S, char x) {if (S->top == MaxSize - 1) { // 栈满,报错return false;} else {S->top = S->top + 1; // 指针先加1S->data[S->top] = x; // 新元素入栈return true;}
}// 出栈
bool Pop(SqStack* S, char* x) {if (StackEmpty(S)) {return false;} else {*x = S->data[S->top]; // 栈顶元素先出栈S->top = S->top - 1; // 指针减1return true;}
}// 括号匹配检查
bool bracketCheck(char str[], int length) {SqStack S;InitStack(&S); // 初始化一个栈for (int i = 0; i < length; i++) {if (str[i] == '(' || str[i] == '[' || str[i] == '{') {Push(&S, str[i]); // 扫描到左括号,入栈} else {if (StackEmpty(&S)) { // 扫描到右括号,且当前栈空return false; // 匹配失败}char topElem;Pop(&S, &topElem); // 栈顶元素出栈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[] = "{([()])}";int length = sizeof(str) / sizeof(str[0]) - 1; // 计算字符串长度,减1是为了去掉结尾的'\0'if (bracketCheck(str, length)) {printf("括号匹配成功\n");} else {printf("括号匹配失败\n");}return 0;
}
栈在表达式求值中的应用
中缀、后缀、前缀表达式
中缀表达式
运算符在两个操作数中间:
- a + b
- a + b - c
- a + b - c * d
后缀表达式
运算符在两个操作数后面:
- ab +
- ab + c-或者a bc - +
- ab + cd * -
前缀表达式
运算符在两个操作数前面:
- + ab
- - + ab c
- - + ab * cd
中缀表达式转后缀表达式(手算)
- 确定中缀表达式中各个运算符的运算顺序
- 选择下一个运算符,按照[左操作数 右操作数 运算符]的方式组合成一个新的操作数(若运算顺序不唯一,则后缀表达式也不唯一)
- 如果还有运算符没被处理,就继续2步骤
例:
转换成后缀表式: 15 7 11+ - / 3 * 2 11 + + -
"左优先"原则:只要左边的运算符能先计算,就优先计算左边的(可保证运算唯一)
中缀表达式转后缀表达式(机算)
代码示例:
要将中缀表达式转换为后缀表达式,可以按照以下步骤进行:
- 初始化一个空栈,用于保存暂时还不能确定运算顺序的运算符。
- 初始化一个空字符串,用于保存最终的后缀表达式。
- 从左到右扫描中缀表达式中的每个字符。
- 对于每个字符,执行以下操作:
- 如果是操作数,直接添加到后缀表达式中。
- 如果是左括号
(
,将其压入栈中。 - 如果是右括号
)
,则弹出栈中的运算符并添加到后缀表达式中,直到遇到对应的左括号(
。左括号(
弹出但不添加到后缀表达式中。 - 如果是运算符(如
+
、-
、*
、/
等),则将栈中所有优先级高于或等于当前运算符的运算符弹出并添加到后缀表达式中。然后将当前运算符压入栈中。
- 扫描完中缀表达式后,将栈中剩余的运算符全部弹出并添加到后缀表达式中。
下面是一个C语言的示例代码,用于将中缀表达式转换为后缀表达式:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_SIZE 100// 栈的结构定义
typedef struct {char items[MAX_SIZE];int top;
} Stack;// 初始化栈
void initStack(Stack* stack) {stack->top = -1;
}// 判断栈是否为空
int isEmpty(Stack* stack) {return stack->top == -1;
}// 判断栈是否满
int isFull(Stack* stack) {return stack->top == MAX_SIZE - 1;
}// 压栈
void push(Stack* stack, char value) {if (isFull(stack)) {printf("Error: Stack is full.\n");return;}stack->items[++stack->top] = value;
}// 出栈
char pop(Stack* stack) {if (isEmpty(stack)) {printf("Error: Stack is empty.\n");return '\0';}return stack->items[stack->top--];
}// 获取栈顶元素
char peek(Stack* stack) {if (isEmpty(stack)) {printf("Error: Stack is empty.\n");return '\0';}return stack->items[stack->top];
}// 操作符优先级
int precedence(char op) {if (op == '+' || op == '-') {return 1;} else if (op == '*' || op == '/') {return 2;} else if (op == '(' || op == ')') {return 0;}return -1;
}// 中缀转后缀
void infixToPostfix(char* infix, char* postfix) {Stack stack;initStack(&stack);int i, j;for (i = 0, j = 0; infix[i] != '\0'; ++i) {if (infix[i] == ' ') continue;else if (isdigit(infix[i]) || isalpha(infix[i])) {postfix[j++] = infix[i];} else if (infix[i] == '(') {push(&stack, infix[i]);} else if (infix[i] == ')') {while (!isEmpty(&stack) && peek(&stack) != '(') {postfix[j++] = pop(&stack);}pop(&stack); // 弹出左括号} else {while (!isEmpty(&stack) && precedence(infix[i]) <= precedence(peek(&stack))) {postfix[j++] = pop(&stack);}push(&stack, infix[i]);}}while (!isEmpty(&stack)) {postfix[j++] = pop(&stack);}postfix[j] = '\0'; // 结束字符串
}int main() {char infix[] = "a+b*(c-d)-e/f";char postfix[MAX_SIZE];infixToPostfix(infix, postfix);printf("Infix: %s\n", infix);printf("Postfix: %s\n", postfix);return 0;
}
后缀表达式的计算(手算)
从左往右扫描,每遇到一个运算符,就让运算符前面最近的两个操作数执行对应运算,合体为一个操作数
注意:两个操作数的左右顺序
后缀表达式的计算(机算)
用栈实现后缀表达式的计算:
- 从左往右扫描下一个元素,直到处理完所以元素
- 若扫描到操作数则压入栈,并回到1;否则执行3
- 若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压回栈顶,回到1
注意:后缀表达式先弹出的元素是‘右操作数’
入栈流程:
中缀表达式转前缀表达式(手算)
- 确定中缀表达式中各个运算符的运算顺序
- 确定下一个运算符,按照[运算符 左操作数 右操作数]的方式组合成一个新的操作数
- 如果还有运算符没被处理,就继续2
"右优先"原则:只要右边的运算符能先计算,就优先算右边的
前缀表达式的计算
- 从右往左扫描下一个元素,直到处理完所有元素
- 若扫描到操作数则压入栈,并回到1;否则执行3
- 若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结构压回栈顶,回到1
注意前缀表达式先弹出的元素是‘左操作数’
栈在递归中的应用
递归调用时,函数调用栈可称为“递归工作栈”
每进入一层递归,就将递归调用所需信息压入栈顶
每退出一层递归,就从栈顶弹出相应信息
- 缺点:太多层递归可能会导致栈溢出
递归算法可能会包含很多重复计算
总结
相关文章:
数据结构(3.8)——栈的应用
栈在括号匹配中的应用 流程图 代码 #include <stdio.h> #include <stdlib.h> #define MaxSize 10typedef struct {char data[MaxSize];int top; } SqStack;// 初始化栈 void InitStack(SqStack* S) {S->top -1; // 初始化栈顶指针 }// 判空 bool StackEmpty(…...
前端面试题35(在iOS和Android平台上,实现WebSocket协议有哪些常见的库或框架?)
在iOS和Android平台上,实现WebSocket协议有许多成熟且被广泛使用的库和框架。下面是一些推荐的选项: iOS 平台 SocketRocket 简介:这是由Facebook开源的库,专门为iOS和Mac OS X设计,提供WebSocket连接的功能。它基于S…...
Mysql如何高效ALTER TABL
ALTER TABLE 缺点 MySQL 的ALTER TABLE 操作的性能对大表来说是个大问题。 MySQL MySQL 执行大部分修改表结构操作的方法是用新结构的 创建一个,空表从旧表中查出所有数据插入,新表然后删除旧。表这样操作可能需要花费很长,时间 如内果存不…...
vue3+vite搭建第一个cesium项目详细步骤及环境配置(附源码)
文章目录 1.创建vuevite项目2.安装 Cesium2.1 安装cesium2.2 安装vite-plugin-cesium插件(非必选)2.3 新建组件页面map.vue2.4 加载地图 3.完成效果图 1.创建vuevite项目 打开cmd窗口执行以下命令:cesium-vue-app是你的项目名称 npm create…...
LiteOS增加执行自定义源码
开发过程注意事项: 源码工程路径不能太长 源码工程路径不能有中文 一定要关闭360等杀毒软件,否则编译的打包阶段会出错 增加自定义源码的步骤: 1.创建源码目录 2. 创建源文件 新建myhello目录后,再此目录下再新建源文件myhello_demo.c 3. 编…...
《Nature》文章:ChatGPT帮助我学术写作的三种方式
图片翻译 ** 文章内容** 忏悔时间:我使用生成式人工智能(AI)。尽管在学术界关于聊天机器人是积极力量还是消极力量的争论不休,但我几乎每天都使用这些工具来完善我所写论文中的措辞,并寻求对我被要求评估的工作进行替…...
防火墙安全策略与用户认证综合实验
一、实验拓扑 二、实验需求 1.DMZ区内的服务器,办公区仅能在办公时间内<9:00-18:00>可以访问,生产区的设备全天可以访问 2.办公区不允许访问互联网,办公区和游客区允许访问互联网 3.办公区设备10.0.2.10不充许访问DMZ区的FTP服务器和HT…...
vue学习day05-watch侦听器(监视器)、Vue生命周期和生命周期的四个阶段、、工程化开发和脚手架Vue cli
13、watch侦听器(监视器) (1)作用:监视数据变化,执行一些业务逻辑或异步操作 (2)语法: 1)简写语法——简单数据类型,直接监视 ① Watch:{ 数…...
数字人+展厅互动体验方案:多元化互动方式,拓宽文化文娱新体验
数字化创新已成为推动展厅可持续发展,创造全新消费体验,满足游客多元化需求的关键力量。 “数字人数字互动展厅”可以适应年轻一代的文化传播与多媒体互动新体验趋势,打造新生代潮玩聚集地,促进文化创意传播与互动体验场景创新&a…...
在Spring Boot项目中集成监控与报警
在Spring Boot项目中集成监控与报警 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 引言 在当今的软件开发中,监控和报警系统是保证系统稳定性和可靠性的重要组成部分。Spring Boot…...
opencv实现目标检测功能----20240704
早在 2017 年 8 月,OpenCV 3.3 正式发布,带来了高度改进的“深度神经网络”(dnn)模块。 该模块支持多种深度学习框架,包括 Caffe、TensorFlow 和 Torch/PyTorch。这次我们使用Opencv深度学习的功能实现目标检测的功能,模型选用MobileNetSSD_deploy.caffemodel。 模型加载…...
音视频解封装demo:使用libmp4v2解封装(demux)出mp4文件中的h264视频数据和aac语音数据
1、README 前言 本demo是使用的mp4v2来将mp4文件解封装得到h264、aac的,目前demo提供的.a静态库文件是在x86_64架构的Ubuntu16.04编译得到的,如果想在其他环境下测试demo,可以自行编译mp4v2并替换相应的库文件(libmp4v2.a&#…...
手撸俄罗斯方块(一)——简单介绍
手撸俄罗斯方块 简单介绍 《俄罗斯方块》(俄语:Тетрис,英语:Tetris),是1980年末期至1990年代初期风靡全世界的电脑游戏,是落下型益智游戏的始祖,电子游戏领域的代表作之一&a…...
构建LangChain应用程序的示例代码:61、如何使用 LangChain 和 LangSmith 优化链
本示例介绍如何使用 LangChain 和 LangSmith 优化链。 设置 我们将为 LangSmith 设置环境变量,并加载相关数据 import osos.environ["LANGCHAIN_PROJECT"] "movie-qa" # 设置 LANGCHAIN_PROJECT 环境变量为 "movie-qa"import pan…...
Android系统通过属性设置来控制log输出的方案
Android系统通过属性设置来控制log输出的方案 背景 项目中经常需要在针对性的模块或者文件,分析问题的时候输出Log,但问题分析完成后,又由于性能问题,需要关闭这些log输出。当前大多数情况下是控制整个系统的log等级来实现&#…...
JavaDoc的最佳实践
文章目录 一、JavaDoc 使用说明1.1 什么是 JavaDoc1.2 文档注释结构1.3 常见的 Javadoc 标签 二、文档最佳实践2.1 注释原则2.2 实际案例 参考资料 一、JavaDoc 使用说明 1.1 什么是 JavaDoc JavaDoc 是一款能根据源代码中的文档注释来产生 HTML 格式的 API 文档的工具。 Jav…...
数字力量助西部职教全面提升——唯众品牌大数据、人工智能系列产品中标甘肃庆阳职院数字经济人才培养基地!
近日,唯众品牌凭借在大数据和人工智能领域深耕多年的技术积累和卓越产品,成功中标庆阳职业技术学院全国一体化算力网络国家枢纽节点数字经济人才培养基地项目,标志着唯众在助力西部职业教育与数字经济融合发展的新征程上迈出了坚实的一步。 …...
Swagger的原理及应用详解(四)
本系列文章简介: 在当今快速发展的软件开发领域,特别是随着微服务架构和前后端分离开发模式的普及,API(Application Programming Interface,应用程序编程接口)的设计与管理变得愈发重要。一个清晰、准确且易于理解的API文档不仅能够提升开发效率,还能促进前后端开发者之…...
Elasticsearch7.10集群搭建
Elasticsearch详细介绍: Elasticsearch 是一个分布式、RESTful 风格的搜索和分析引擎。它的核心基于 Apache Lucene,能够处理海量的数据,并支持实时的全文搜索。以下是关于 Elasticsearch 的详细介绍。 一、基本概念 索引(Index…...
SMU Summer 2024 Contest Round 3
A.Hcode OnlineJudge 先用欧拉筛把质数预处理出来,然后枚举左端点的质数,只需要询问右端点是不是质数并取差值的min就行了 #include<bits/stdc.h> #define endl \n #define mk make_pair #define int long long using namespace std; typedef lon…...
uniapp 封装瀑布流组件
思路: 1.coulumns:需要分成几列 2.如何分布数据 3.计算每列的宽度 4.图片进行高度自适应 <template><view :style"{ margin: boxM }"><view class"flex flex-justify-start bg-red" style"background-colo…...
pd虚拟机去虚拟化是什么意思?pd虚拟机去虚拟化教程 PD虚拟机优化设置
Parallels Desktop for Mac(PD虚拟机)去虚拟化是指在虚拟机(Virtual Machine,简称 VM)中禁用或减少虚拟化层的影响,使其表现更接近于物理机。这种操作通常用于提高虚拟机的性能或解决某些软件兼容性问题。具…...
低代码研发项目管理流程优化:提效与创新的双重驱动
随着信息技术的迅猛发展,软件项目的规模和复杂度日益增加,传统的软件开发方式已经难以满足快速迭代和高效交付的需求。在这一背景下,低代码平台应运而生,以其高效、灵活、易用的特点,迅速成为软件行业的新宠。然而&…...
32位版 C 库函数time 将在 2038 年溢出,那到时候,它该何去何从
简单地说,通常不必担心,在64位操作系统已经成为主流的今天这基本上不是问题(在写这篇回答的时候,我才发现我甚至找不到32位的机器来测试)刚好我有一些资料,是我根据网友给的问题精心整理了一份「32库函数的…...
C语言 printf函数缓冲机制
printf不立即打印到stdout的原因 printf函数使用了缓冲机制。当我们调用printf时,输出通常不会立即显示在屏幕上,而是先存储在一个缓冲区中。这是为了提高I/O操作的效率。 缓存数据输出的原理 stdio库维护了一个缓冲区。当缓冲区满了,或者在特定条件下,缓冲区的内容会被刷新…...
【Linux进阶】文件系统8——硬链接和符号连接:ln
在Linux下面的链接文件有两种, 一种是类似Windows的快捷方式功能的文件,可以让你快速地链接到目标文件(或目录);另一种则是通过文件系统的inode 链接来产生新文件名,而不是产生新文件,这种称为硬链接&…...
代码随想录算法训练营Day64|拓扑排序(卡码网117)、dijkstra朴素版
拓扑排序 117. 软件构建 (kamacoder.com) 拓扑排序简单的说是将一个有向图转为线性的排序。 它将图中的所有结点排序成一个线性序列,使得对于任何的边uv,结点u在序列中都出现在结点v之前,这样的序列满足图中所有的前驱-后继关系。 拓扑排…...
neo4j 图数据库:Cypher 查询语言、医学知识图谱
neo4j 图数据库:Cypher 查询语言、医学知识图谱 Cypher 查询语言创建数据查询数据查询并返回所有节点查询并返回所有带有特定标签的节点查询特定属性的节点及其所有关系和关系的另一端节点查询从名为“小明”的节点到名为“小红”的节点的路径 更新数据更新一个节点…...
数据结构基础--------【二叉树基础】
二叉树基础 二叉树是一种常见的数据结构,由节点组成,每个节点最多有两个子节点,左子节点和右子节点。二叉树可以用来表示许多实际问题,如计算机程序中的表达式、组织结构等。以下是一些二叉树的概念: 二叉树的深度&a…...
数据开源 | Magic Data大模型高质量十万轮对话数据集
能够自然的与人类进行聊天交谈,是现今的大语言模型 (LLM) 区别于传统语言模型的重要能力之一,近日OpenAI推出的GPT-4o给我们展示了这样的可能性。 对话于人类来说是与生俱来的,但构建具备对话能力的大模型是一项不小的挑战,收集高…...
h5网站开发软件下载/站长之家官网登录入口
问题 Push failed: fatal: Authentication failed for httpspycharm invalid authentication data couldn’t kickstart handshaking 解决...
广东省住房和城乡建设部网站/建网络平台要多少费用
1、大力敲击回车键这个恐怕是人所共有的通病了,因为回车键通常是我们完成一件事情时,最后要敲击的一个键,大概是出于一种胜利的兴奋感,每个人在输入这个回车键时总是那么大力而爽快地敲击。本人的多个键盘就是这样报废…...
湖南城市建设技术学院官方网站/长沙线上引流公司
以前学习oc的时候写的一个团购的项目,现在学习swift,拿来用swift写一遍,也是连猜带蒙的,一点一点的往上凑。 今天主要是把主要的架子搭起来了。 主要有:UITabBarController,UINavigationController…...
做网站的备案/离我最近的电脑培训中心
MP3播放器的工作原理MP3播放器是利用数字信号处理器DSP来完成处理传输和解码MP3文件的任务的。DSP掌管播放器的数据传输,设备接口控制,文件解码回放等活动。MP3工作方框图(图1) 一个完整的MP3播放器要分几个部分:中央处…...
wordpress tinymce 代码高亮/互联网平台公司有哪些
项目介绍 一款 PHP 语言基于 Laravel9.x、Layui、MySQL等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本着简化开发、提升开发效率的初衷,框架自研了一套个性化的组件&…...
如何做公司的英文网站/广州seo团队
PageHelper是一个开源的MyBatis分页插件。它可以通过拦截器来实现自动分页。PageHelper拦截器会在查询语句执行之前拦截它并自动为其添加分页参数。PageHelper可以支持各种不同类型的数据库,包括MySQL、Oracle和PostgreSQL等。 PageHelper非常易于使用,只…...