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

数据结构(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;
}

栈在表达式求值中的应用

中缀、后缀、前缀表达式

中缀表达式

运算符在两个操作数中间:

  1. a + b
  2. a + b - c
  3. a + b - c * d

后缀表达式

运算符在两个操作数后面:

  1. ab +
  2. ab + c-或者a bc - +
  3. ab + cd * -

前缀表达式

运算符在两个操作数前面:

  1. + ab
  2. - + ab c
  3. - + ab * cd

中缀表达式转后缀表达式(手算)

  1. 确定中缀表达式中各个运算符的运算顺序
  2. 选择下一个运算符,按照[左操作数 右操作数 运算符]的方式组合成一个新的操作数(若运算顺序不唯一,则后缀表达式也不唯一)
  3. 如果还有运算符没被处理,就继续2步骤

例:

转换成后缀表式:          15 7 11+ - / 3 *  2 11 + + -

"左优先"原则:只要左边的运算符能先计算,就优先计算左边的(可保证运算唯一)

后缀表达式的计算(手算)

从左往右扫描,每遇到一个运算符,就让运算符前面最近的两个操作数执行对应运算,合体为一个操作数

注意:两个操作数的左右顺序

后缀表达式的计算(机算)

用栈实现后缀表达式的计算:

  1. 从左往右扫描下一个元素,直到处理完所以元素
  2. 若扫描到操作数则压入栈,并回到1;否则执行3
  3. 若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压回栈顶,回到1

注意:后缀表达式先弹出的元素是‘右操作数’

入栈流程:

 中缀表达式转前缀表达式(手算)

  1. 确定中缀表达式中各个运算符的运算顺序
  2. 确定下一个运算符,按照[运算符 左操作数 右操作数]的方式组合成一个新的操作数
  3. 如果还有运算符没被处理,就继续2

"右优先"原则:只要右边的运算符能先计算,就优先算右边

前缀表达式的计算

  1. 从右往左扫描下一个元素,直到处理完所有元素
  2. 若扫描到操作数则压入栈,并回到1;否则执行3
  3. 若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结构压回栈顶,回到1

注意前缀表达式先弹出的元素是‘左操作数’

总结

相关文章:

  • gdb调试命令大全
  • 【产品经理】订单处理11-订单修改场景梳理
  • 泛微开发修炼之旅--29用计划任务定时发送邮件提醒
  • RISC-V在当前计算架构中的地位
  • 使用Vue CLI方式创建Vue3.0应用程序
  • 如何在Java项目中实现领域驱动设计(DDD)
  • 2024华为OD机试真题-找数字-(C++/Python)-C卷D卷-200分
  • 【BUUCTF-PWN】7-[第五空间2019 决赛]PWN5
  • 【大模型LLM面试合集】大语言模型基础_激活函数
  • 金斗云 HKMP智慧商业软件 任意用户创建漏洞复现
  • 《Windows API每日一练》6.2 客户区鼠标消息
  • 【Java09】方法(下)
  • 免费办公软件 -- LibreOffice v24.2.4
  • 2024 年最佳 Figma 字体
  • STM32学习历程(day2)
  • [译]CSS 居中(Center)方法大合集
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Java比较器对数组,集合排序
  • Laravel 中的一个后期静态绑定
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • PAT A1120
  • React中的“虫洞”——Context
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • vue中实现单选
  • Webpack 4 学习01(基础配置)
  • 从setTimeout-setInterval看JS线程
  • 基于HAProxy的高性能缓存服务器nuster
  • 少走弯路,给Java 1~5 年程序员的建议
  • 首页查询功能的一次实现过程
  • 算法-图和图算法
  • 通过git安装npm私有模块
  • 协程
  • 携程小程序初体验
  • 智能网联汽车信息安全
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​ssh免密码登录设置及问题总结
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #vue3 实现前端下载excel文件模板功能
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (原創) 未来三学期想要修的课 (日記)
  • .CSS-hover 的解释
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET 发展历程
  • .NET 设计一套高性能的弱事件机制