一起talk C栗子吧(第二十一回:C语言实例--表达式求值)

各位看官们,大家好,前几回中咱们说了堆栈的原理,并且举了实际的例子进行解说,这一回咱们说的例

子是:表达式求值。表达式求值和上一回中说的括号匹配一样,都使用了堆栈的原理,大家可以从例子中

看出来,所以我们把它们放在一起。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们,我们在这里说的表达式为包含加,减,乘除的四则运算表达式。例如:1+2*3-4/5就是一个四则运

算表达式。这个表达式中,运算符在数字中间,所以我们叫它中缀表达式,这也是符合我们思维的一种表

现形式,不过,计算机就不理解中缀表达式了,因为它没有办法像我们一样先进行乘除运算,然后再进行

加减运算,所以我们需要把中缀表达式转换成计算机能理解的后缀表达式。“什么是后缀表达式”,这时候

台下有看官在提问了,看官莫急,所谓的后缀表达式就是运算符在数字后面。例如:" 1+2*3-6/3 "这个中缀

表达式可以为" 123*+63/- "这种后缀表达式.

表达式求值有两个大的步骤:

  • 中缀表达式转换为后缀表达式。
  • 对后缀表达式进行求值。

这两个大的步骤中还有一些小的步骤,接下来我们详细说说这些小步骤。在说之前,我首先说明一个概念:优

先级。优先级代表着先后顺序,举一个日常为生活中的例子:排队买东西的时候,排在队列前面的人,比排在

队列后面人具有优先买东西的权利,我们就可以说:排在队列前面的人买东西的优先级高。优先级在表达式运

算过程中体现为:乘法和除法的优先级比加法和减法的优先级高。也就是我们通常说的先乘除后加减,这个内

容我就不多说了,大家在小学数学中都学过。我们在表达式求值过程中把中缀表达式转换为后缀表达式也与优

先级有关,因为后缀表达式可以去掉运算符的优先级。没有优先级了,计算机就能理解后缀表达式并对其进行

相关的运算。

中缀表达式转换为后缀表达式的步骤如下:

1.从头到尾依次遍历中缀表达式,每次从表达式中读取一个字符;

2.判断步骤1中读取的字符,如果是数字则保存到数组a中,如果是+*等运算符,请看下一个步骤;

3.对存放运算符的栈进行出栈操作,把步骤的2中的运算符和刚才出栈的运算符进行优先级比较;

4.如果步骤2中的运算符优先级高,那么把参与比较的这两个运算符都入栈。否则看下一步;

5.如果步骤2中的运算符优先级低,那么让栈中的运算符继续出栈,并且把出栈的运算符存放数组a中;

6.重复步骤4和步骤5,直到出栈运算符的优先级比步骤2中运算符的优先级高为止;

7.重复步骤1到步骤6.直到遍历完中缀表达式为止;

8.判断栈中是否还有运算符,如果有的话,就把所有运算符出栈,并且把出栈的运算符存放数组a中。

对后缀表达式求值的步骤如下:

1.从头到尾依次遍历后缀表达式,每次从表达式中读取一个字符;

2.判断步骤1中读取的字符,如果是数字则入栈,如果是+*等运算符,请看下一个步骤;

3.对存放数字的栈进行两次出栈操作,依据步骤2中运算符的类型,对出栈的两个数字进行运算;

4.对步骤3中的运算结果进行入栈操作,这样可以把运算结果保存到存放数字的栈中;

5.重复步骤1到步骤4.直到遍历完后缀表达式为止;

6.栈中最后一个元素就是该表达式的运算结果。

看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击链接下载使用。从代码中可

以看到,我们用了两次栈,一次是在中缀表达式转换成后缀表达式的过程中,栈用来存放运算符。另外一

次是在后缀表达式求值的过程中,栈用来存放参与运算的数字。

各位看官,关于括号匹配的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 09:32:31

一起talk C栗子吧(第二十一回:C语言实例--表达式求值)的相关文章

11、蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现

11.蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现 本篇名言:"人生不售来回票,一旦动身,绝不能复返." 继续栈应用实现,这次是来看下表达式求值的栈实现. 欢迎转载,转载请标明出处: 1.  表达式求值 表达式求值是设计语言编译中的一个基本问题,它的实现是栈应用的又一个典型例子. 任何一个表达式都是由操作数(Operand).运算符(operator)和界限符(delimiter)组成. 操作数可以是常数也可以是变量或变量的标识符. 运算符可以分为算术运算符.关系运算符和逻辑运算符

第二十一章、使用查询表达式来查询内存中的数据

什么是语言集成查询(LINQ) 对从应用程序代码中查询数据的机制进行了“抽象”.这个功能称为“语言集成查询”(Language Integrated Query). LINQ的设计者大量借鉴了关系数据库管理系统(例如Microsoft SQL Server)的处理方式,将“数据库查询语句”与“数据在数据库中的内部格式”分隔开.LINQ的语法和语义和SQL很像,具有许多相同的优势.要查询的数据的内部结构发生改变后,不必修改查询代码.注意,虽然LINQ和SQL看起来很像,但LINQ更加灵活,而且能处

一起talk Vim吧(第二十一回:Vim插件之NerdTree续)

各位看官们,大家好,欢迎大家一起来听大型章回体科技小说 :Vim.上一回咱们介绍了Vim中的NerdTree 插件..这一回,咱们继续说NerdTree插件,不过咱们上一回说的是如何安装该插件,这一回咱们说的是 如何使用该插件.好了,还是那句话,闲话休提,言归正转.让我们一起talk Vim吧! 看官们,咱们先来说说NerdTree的基本操作.具体如下: h j k l 这几个键在目录窗口中的操作和VIM一样,这里不做详细说明. J K表示到最上/下面的目录,当目录很长时,它们很方便. q表示关

一起talk C栗子吧(第二十二回:C语言实例--队列一)

各位看官们,大家好,上一回中咱们说的是表达式求值的例子,该例子使用了栈,这一回咱们说的是栈的 兄弟:队列.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在这里说的队列是一种抽象的数据结构,大家不用想的太抽象了,哈哈,其实它和我们日常生活中所 见的队列一样.不管怎么样,我们还是举一个容易理解的例子:大家在假期出去旅游的时候,都有过排队 买门票的经历吧.游客们在售票点的窗口前排成了一长串队列,售票人员先把门票卖给排在队列前面的游 客,买到门票的游客拿着门票兴高采烈地离开了队列,刚来到售票点

一起talk C栗子吧(第一百二十一回:C语言实例--线程知识体系图)

各位看官们,大家好,上一回中咱们说的线程属性的例子,这一回咱们说的例子是:线程知识体系图.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在前面的章回中介绍了与线程相关的知识,在今天的章回中,我们将对这些知识进行总结,并且整理成一张知识体系图,方便大家掌握线程相关的知识. 下面是我们整理的知识体系图,请大家参数: 上图内容中的知识点都有相应的章回对应,下面是我整理的章回对应关系.为了大家方便,我设置了链接,大家可以直接点击链接跳到相应的章回中. 线程概念 线程概念:第一百零七回 线程标识

一起talk C栗子吧(第十一回:C语言实例--文件组织结构)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是最小公倍数的例子,这一回咱们不说具体的例子,咱们说一下C例子中的文件 组织方法以及实际开发软件时的"文件组织结构方法". 看官们,在我前面写的例子中,只有一个源文件(也就是通常看到的.c文件).我没有单独写头文件(也 就是通常看到的.h文件),而是把头文件的内容放到了源文件中.主要是这些例子中关于头文件的内容不 多,如果单

一起talk C栗子吧(第三十五回:C语言实例--测试程序运行时间)

各位看官们,大家好,上一回中咱们说的是巧用溢出计算最值的例子,这一回咱们说的例子是:测试程序 运行时间.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,在编写程序的时候,可能需要计算程序运行的时间.通过计算时间,可以查看程序的性能.其实 我们在第三十一回中对各种常用排序算法总结时也使用过这种方法,不过当时使用的是Linux提供的time 命令.如果大家忘记了第三十一回的内容,可以点击这里查看. 我们今天说的测试程序运行时间,是让程序自己测试运行时间,而不是像第三十一回中哪样借用其它工

一起talk C栗子吧(第一百七十四回:C语言实例--关闭终端中的缓冲功能二)

各位看官们,大家好,上一回中咱们说的是关闭终端中缓冲功能的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们, 我们在上一回中介绍了如何关闭终端中的缓冲功能,当时是借助系统命令stty实现该功能的,这一回中我们将介绍另外一种关闭终端中回显功能的方法.该方法是通过终端的termios编程接口来操作终端的.关于termios接口的介绍和编程接口,我们在一百七十一回中介绍过了,因此,我们直接介绍如何通过termios编程接口来关闭终端缓冲功能. 下面是详细的操作步

一起talk C栗子吧(第一百一十六回:C语言实例--线程同步之互斥量二)

各位看官们,大家好,上一回中咱们说的是线程同步之信号量的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在上一回中详细介绍了互斥量相关函数的用法,这一回中,我们介绍如何使用这些函数来操作互斥量. 下面是详细的操作步骤: 1.定义一个互斥量A,用来同步线程: 2.在创建线程的进程中使用pthread_mutex_init函数初始化互斥量,互斥量的属性使用默认值: 3.在读取数据的线程中读取数据,首先使用pthread_mutex_lock函数对互斥量A进行加锁