数据结构之栈在表达式求值及转换中的应用

  • 1 栈及表达式的基本定义
  • 2 栈在表达式求值过程以及转换中的应用

1 栈及表达式的基本定义

1.1栈的定义

栈(stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,
表尾端有其特殊含义,称为栈顶(top),相应地,表头端称为栈底(bottom)。不含元素的空表称为空栈。栈也称为后进先出表。下面将给出关于栈基本操作的相关函数:
InitStack(&S):构造一个空栈S
GetTop(S,&e):用e返回S的栈顶元素。
Push(&S,e):插人元素e为新的栈顶元素。
Pop(&s,&e):删除S的栈顶元素,并用e返回其值。
Precede(m,n):运算符的优先级比较函数。

1.2表达式的定义

任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(elimite)组成的,我们称它们为单词。一般地,操作数既可以是常数也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符3类;基本界限符有左右括号和表达式结束符等。

1.3表达式的分类

表达式一般分为前缀表达式,中缀表达式和后缀表达式,在计算机中,计算后缀表达式值的时间空间消耗往往比计算中缀表达式的消耗少,因此我们通常将普通表达式转化为某种类型表达式来达到减少复杂度的目的。
1.3.1 前缀表达式 前缀表达式是将运算符写在前面,操作数写在后面。为纪念其发明者波兰数学家Jan Lukasiewicz,前缀表达式也称为“波兰式”。
1.3.2 中缀表达式 中缀表达式是指运算符在两个操作数的中间。即平时常用的表达式脱括号后的形式。
1.3.3.后缀表达式 后缀表达式是将运算符放在两个运算对象的后面,计算时按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。运用次数最多,又称“逆波兰式”。
对于算术表达式Exp=ab+(c-d/e)f,它的三种表达形式为:前缀式:+ab-c/def,中缀式:ab+c-d/ef,后缀式:abcde/-f+。

1.4关于上述表达式的相关结论

1.操作数之间的相对次序不变;
2.运算符的相对次序不同;
3.中缀式丢失了括弧信息,致使运算的次序不确定;
4.前缀式的运算规则为:连续出现的两个操作数和在它们之前且紧靠它们的运算符构成一个最小表达式;
5.后缀式的运算规则为:运算符在式中出现的顺序恰为表达式的运算顺序;每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式。

2 栈在表达式求值过程以及转换中的应用

2.1 表达式求值算法的基本思路

为了叙述的简洁,我们仅讨论简单算术表达式的求值问题。这种表达式只含加、减、乘、除4种运算符。读者不难将它推广到更一般的表达式上。
2.1.1 求值算法中的主要数据结构 我们分别用顺序栈来寄存表达式的操作数和运算符。为了实现算符优先算法,可以使用两个工作栈。一个称做OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。
2.1.2 关于表达式的分析与判断 表达式求值程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。可以建立两个栈,分别存储数字与运算符,栈OPTR存运算符,栈OPND存数字。依次读取表达式的字符串。读取字符的时候需要判断字符的类型,先判断是数字还是运算符:
第一步,如果是数字,把数字压入栈OPND。
第二步,如果是运算符,那么在压入运算符之前,先将要压入的与栈顶的运算符优先级相比较,此时有三种情况:
1.如果当前的运算符优先级等于栈顶,则脱括号并接受下一字符;
2.若当前的运算符优先级大于栈顶的,则压入;
3.若当前的运算符优先级小于栈内时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。
为了方便判断运算结束,在存储运算符之前先将“#”压入栈OPTR中,在输入表达式时以“#”结束,所以当接受的运算符为‘#’并且OPTR栈顶的元素也为‘#’来作为运算结束的条件,经过上述的讨论,最后栈OPND的数值,即为表达式求值的最终结果。
2.1.3 表达式求值例题分析
例1:利用上述算法对算数表达式3*(7-2)求值
下图中,左侧为OPTR栈,右侧为OPND栈。
步骤1:“#”入OPTR栈

                                        图1

步骤2:“3”入OPND栈

                               图2

步骤3:“”比此时的OPTR栈的顶元素“#”的优先权高,“”入OPTR栈

步骤4.:“(”比此时的OPTR栈顶元素“*”的优先权高,“(”入OPTR栈

步骤5:“7”是数字,进OPND栈

步骤6.:“-”比此时的OPTR栈顶元素“(”的优先权高,“-”入OPTR栈

步骤7.:“2”入OPND栈

            图7

步骤8.:“)”比此时的OPTR栈顶元素“-”的优先权低,执行Pop(OPTR,theta);操作,“-”退OPTR栈,OPND栈中退出两个数,在该步操作中执行“7-2”,把得到的结果5压入OPND栈中,此时两个栈的元素为下图:

                               图8

步骤9:“)”继续和OPTR栈此时的栈顶元素“(”相比,发现相等,则脱括号,并接受下一字符,此时的OPND栈为:

                图9

步骤10:我们通常以“#”来作为表达式的末尾,所以最后需要判断优先级大小的是“#”和OPTR的栈顶元素“”,此时发现栈顶元素“”的优先级高,则栈顶元素“”出栈,OPND栈中出两个元素,执行“35”操作,得到15,压入OPND栈内,最后两个“#”相等,while循环结束。则OPND栈中的元素就是该表达式的最终求值。此时,两个栈的元素为:

                 图10

最后结果为3*(7-2)=15。
2.1.4 算法时间和空间性能分析
1.时间复杂度:对于含n个字符的表达式,无论是对其进行合法性检测还是对其进行入栈出栈操作n次,因此其时间复杂度为0(n)。
2.空间复杂度:由于在本程序中,在为算符栈(OPTR)和操作数栈(0PND)涉及到两种情况时申请空间,一方面分别为OPTR栈和0PND栈申请了初始的存储单元,均为STACKINITSIZE=100个;另一方面,考虑到两个栈在处理具体的算术表达式时,有可能会出现溢出的情况,即栈的初始的存储空间不够用,这时需要为其申请额外的存储空间,每溢出一次,就为其申请存储单元STACKINCREMENT=10个,所以,本程序的算法的空间复杂度一方面取决于算术表达式的长度,另一方面取决于本程序的所有代码所占用的存储空间大小。

2.2 后缀表达式求值算法
2.2.1求值算法中的主要数据结构 根本思想就是先找运算符,再找操作数,因为操作数来的早晚与运算顺序无关,所以,我们可以设置一个栈来存储操作数,只要是操作数据进栈,只要是运算符就从栈中取出两个操作数,经过运算符的运算后再重新压到栈内,最后栈顶的值就是我们要求的最后结果。

2.2.2基于C语言的算法
下面给出其基本算法:
int GetValue NiBoLan(char *str)/对逆波兰式求值
{ p=str;InitStack(s); //s为操作数栈
while(*p!="#’)
{ if(Isdigit(*p)) push(s,*p);
else {
pop(s,a);pop(s,b);
r=compute(b,*p,a); //假设compute为执行双目运算的过程
push(s,r);}//else
}//while
}//GetValue_ NiBoLan

2.3 原表达式求后缀表达式算法

2.3.1 原表达式求后缀式算法思想 因为运算符来的早晚与运算顺序无关,首先设立暂存运算符的栈,设表达式的结束符号为“#”,预设运算符栈的栈底为“#”,若当前字符是操作数,则直接发送给后缀式;若当前运算符的优先数高于栈顶运算符,则进栈;否则,退出栈顶运算行发送给后缀式;“(”对它之前后的运算符起隔离作用,“)”可视为自相应左括弧开始的表达式的结束符。
2.3.2 原表达式求后缀式例题分析
对原表达式2*(9+6/3-5)+4求其后缀式:

最后求得后缀表达式为:2963/+5-*4+。

参考文献:
[1] 严蔚敏,吴伟民.数据结构C语言版[M].北京:清华大学出版社。

这是自己总结的表达式求值的基本算法,也是自己的写的一篇很简单的课程论文,主要是给出了相应的例题分析,图片是自己做的,不是很美观,有错误欢迎大家评论区指出讨论,大家一起进步!

数据结构-栈--表达式相关推荐

  1. 怎么删除结构体数组中的一组数据_数据结构-栈

    数据结构-栈 1)栈的定义. 栈是只能通过访问它的一端来实数据存储和检索的一种线性数据结构,逻辑结构和线性表相同.特点在于运算有所限制:即主要特征是"后进先出"(先进后出). 在栈 ...

  2. JVM【带着问题去学习 02】数据结构栈+本地方法栈+虚拟机栈+JVM栈运行原理

    1.数据结构栈 栈是一种比较简单的数据结构,后进先出.栈本身是一个线性表,但是这个表中只有一端允许数据的进出.栈的常用操作包括入栈push和出栈pop,对应于数据的压入和弹出.由于栈后进先出的特性,常 ...

  3. 猿创征文 |【算法入门必刷】数据结构-栈(四)

    [算法入门必刷]算法入门-数据结构-栈(四) 前言 算法入门刷题训练 AB4:逆波兰表达式求值 题目分析 理论准备 题解 小结

  4. 数据结构——栈的使用

    title: 数据结构--栈的使用 categories: 数据结构 tags: 数据结构 abbrlink: 332301884 date: 2019-11-06 19:11:43 栈的定义 栈只允 ...

  5. c语言特殊计算器设计报告,C语言数据结构栈计算器的实现课题设计报告书

    C语言数据结构栈计算器的实现课题设计报告书 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 目录1. 课程设计任务 12. 需求分析 ...

  6. 数据结构——栈与队列相关题目

    数据结构--栈与队列相关题目 232. 用栈实现队列 思路 225. 用队列实现栈 1.两个队列实现栈 2.一个队列实现栈 20. 有效的括号 思路 1047. 删除字符串中的所有相邻重复项 思路 1 ...

  7. 【数据结构】--表达式求解----完整版

    数据结构之表达式求解----完整版(无敌完整版) (1) 运算符包括:+.-.*.-.^(乘方).括号 (2)实数(包括多位整数各种): 表达式的书写形式 中缀--日常写的,但是他的计算方式较为复杂 ...

  8. 数据结构栈队列链表数组

    目录: 数据结构 栈(stack) 队列 链表 数组 数据结构 数据结构是什么 简单来说,数据结构就是设计数据以何种方式存储在计算机中 比如:列表,集合,与字典等都是一种数据结构 程序 = 数据结构 ...

  9. php+spl+栈,PHP SPL标准库之数据结构栈(SplStack)介绍

    PHP SPL标准库之数据结构栈(SplStack)介绍2020-06-13 22:01:42 栈(Stack)是一种特殊的线性表,因为它只能在线性表的一端进行插入或删除元素(即进栈和出栈) SplS ...

最新文章

  1. 好看的dialog,sweet Alert Dialog 导入Android Studio
  2. 一口气用 Python 写了13个小游戏,摸鱼达人!
  3. CSS 负边距自适应布局
  4. 【转】ABP源码分析四十六:ABP ZERO中的Ldap模块
  5. [BZOJ1669][Usaco2006 Oct]Hungry Cows饥饿的奶牛
  6. git 分支的创建和切换
  7. WiredTiger存储引擎知多少?
  8. mysql重建索引_mysql创建、删除、重建、删除索引的操作命令的一些总结
  9. Android监听作用,Android开发之CheckBox的简单使用与监听功能示例
  10. 【PL/SQL】PL/SQL语言基础
  11. 凸优化第二章凸集 2.1 仿射集合和凸集
  12. 计算机专业新手小白学编程如何选择笔记本电脑
  13. 「网络安全专利分析」一种基于多粒度异常检测的网络威胁评估方法
  14. arctanx麦克劳林公式推导过程_点到线的距离公式推导过程
  15. 【用例】研究生招生报名管理系统分析
  16. 条码生成软件如何批量生成Code39码
  17. 怎样绘制英语学习思维导图?简单的方法介绍
  18. VIN码含义及其算法
  19. ToList()方法
  20. 高德地图开发常用API

热门文章

  1. 如何制作PechaKucha的PPT?
  2. 利用Arcgis制作2019年重庆主城新区GDP地图
  3. Brinson多期归因计算示例
  4. 笔记:表单验证以及sweetalert中swal的使用
  5. 跨链技术的分析和思考
  6. svg通过虚线画形状
  7. 语音对讲系统在车载管理系统应用
  8. 计算机黑科技ppt英文,微软黑科技:PPT全文翻译
  9. 一体机性能服务器图片介绍,一体机服务器
  10. RocketMQ的负载均衡