到现在为止,本章已经介绍了三种不同的数据存储结构。现在,转换一下,把注意力集中到一个实际应用问题上来。这个应用是解析(也可以说是分析)算术表达式,例如2+3,或者2*(3+4),或者((2+4)*7)+3*(9-5)等。它用到的存储结构是栈。brackets.java程序(清单4.3)已经演示了怎样应用栈来检查分隔符是否正确匹配的问题。这和应用栈解析算术表达式的方法类似,尽管后者更为复杂。
从某种意义上来说本节内容应作为选学内容。它不是本书后面章节的必修内容,并且除非是专门编写编译器或者是要设计便携式计算器的程序员,人们不会每天编写代码来解析算术表达式。另外,此应用的详细代码也比前面的程序复杂得多。但是这个重要的应用对于学习栈很有意义,而且这个应用本身引起的问题也非常有意思。
事实上,至少对计算机的算法来说如果要直接求算术表示式的值,还是相当困难的。因此分两步实现算法会更容易:
1. 将算术表达式转换成另一种形式:后缀表达式。
2. 计算后缀表示式的值。
第一个步骤比较难,但是第二步很简单。但是不管怎么说,这种分两步的算法比直接解析算术表达式的方法容易。当然,对人类来说,还是解析普通的算术表达式容易。稍后将会再讨论人类和计算机的方法的差别。
在研究步骤1和步骤2的具体实现之前,先来介绍后缀表达式。
后缀表达式
日常算术表示式是将操作符(operator)(+,-,*,/)放在两个操作数(operands)(数字,或代表数字的字母)之间的。因为操作符写在操作数的中间,所以把这种写法称为中缀表达法。于是,日常我们写的算术表示式就形如2+2,4/7,或者用字母代替数字,如A+B和A/B等。
在后缀表达式中[也称作波兰逆序表达式(Reverse Polish Notation)],或者RPN,它是由一位波兰的数学家发明的],操作符跟在两个操作数的后面。这样,A+B就成为AB+,A/B成为AB/。更复杂的中缀表达式同样可以转换成后缀表达式,如表4.2所示。稍后会解释后缀表达式是如何产生的。
表4.2 中缀表达式和后缀表达式
中缀表达式 | 后缀表达式 |
A+B-C | AB+C- |
A*B/C | AB*C/ |
A+B*C | ABC*+ |
A*B+C | AB*C+ |
A*(B+C) | ABC+* |
A*B+C*D | AB*CD*+ |
(A+B)*(C-D) | AB+CD-* |
((A+B)*C)-D | AB+C*D- |
A+B*(C-D/(E+F)) | ABCDEF+/-*+ |
有些计算机语言也用一个操作符表示乘方(通常,用‘^’符号),但在这里暂不讨论这种表示。
除了中缀和后缀表达法,还有一种前缀表达法,操作符写在两个操作数的前面:用+AB代替AB+。这种表达法与后缀表达法功能类似,但是很少使用。
把中缀表达式转换成后缀表达式
下面的内容解释怎样把中缀表达的算术表达式转换成后缀表达式。这个算法时相当难的,因此刚开始要是没有完全明白也不必担心。如果很难理解这一部分,可以先跳到“求后缀表达式的值”这一节。为了理解怎样创建后缀表达式,先看怎么计算后缀表达式的值会有所帮助;
分享到:
相关推荐
使用栈结构解析算术表达式,加、减、乘、除、求余,并支持多位数运算
用栈解析算术表达式,并且做到了多位数运算,运算包括加、减、乘、除、求余
java正则实现解析算术表达式 (仅限+-*/和括号)
在给定的代码中,作者使用了一个 parse 函数来实现解析算术表达式的过程。 7. 二叉树的前序遍历(Pre-Order Traversal) 二叉树的前序遍历是一种树遍历算法,其中先访问当前节点,然后访问左子树和右子树。在给定...
1. **解析算术表达式**: 解析是将字符串形式的算术表达式转换成抽象语法树(AST)的过程。AST是一种树形结构,其中每个节点代表表达式的一部分,如操作数、运算符或括号内的子表达式。解析可以采用不同的方法,如...
在这个场景中,我们关注的是一个用Java编写的专门用于解析算术表达式的解释器。Java是一种广泛使用的面向对象的编程语言,以其跨平台性和强大的库支持而著名。下面我们将深入探讨Java解释算术表达式这一主题。 首先...
算符优先法是一种用于解析算术表达式的有效方法,特别是对于处理四则运算表达式时尤为有用。通过本项目,我们将深入探讨如何使用算符优先法来实现一个简单的程序,该程序能够接受标准输入的算术表达式并输出其计算...
在数据结构课程设计中,"二叉树表示的算术表达式"是一个常见的主题,它涉及到计算机科学的基础概念,特别是二叉树、数据结构以及如何用它们来解析和操作算术表达式。在这个项目中,我们将深入探讨这些知识点,并了解...
在IT领域,开发一个能解析和计算算术表达式的程序是一项基础且重要的任务。这个程序通常涉及词法分析(Lex)和语法分析(Yacc)这两个编译原理的关键步骤。让我们详细了解一下这些概念以及如何利用它们来实现一个...
本文是关于数据结构算术表达式的求解的大学毕业论文,主要介绍了算术表达式的解析和求解过程,使用了数据结构课程设计题的思路来分析和解决问题。下面是本文的知识点摘要: 一、算术表达式的定义和类型 算术表达式...
算符优先文法是编译原理中的一种解析技术,它用于处理和解析算术表达式,以确保其结构正确并能被准确地计算。本文将详细介绍算符优先文法在判断算术表达式正确性中的应用,并结合提供的源代码、说明文档和输入输出...
总之,这个项目实现了一个用C语言编写的递归下降语法分析器,专门用于解析算术表达式。通过这种方式,我们可以将源代码中的复杂表达式转化为易于处理的数据结构,为后续的编译或解释过程奠定基础。这种解析方法不仅...
本项目的目标是设计一个C++源程序,用于解析给定的算术表达式。根据描述,提供的算术表达式文法如下: ```markdown E -> E + T | T T -> T * F | F F -> (E) | i ``` 这个文法定义了一个简单的算术表达式结构,...
* 能够正确地解析算术表达式,包括加法、减法、乘法、除法等运算符。 * 能够正确地计算算术表达式的结果。 * 能够处理算术表达式中的错误,包括语法错误和语义错误。 2. 选题目的及意义 本课程设计的目的是为了...
3. **运算符优先级**: 在解析算术表达式时,需要遵循运算符的优先级规则,例如乘法和除法优先于加法和减法。为了正确计算,我们需要对运算符的优先级进行管理。 4. **后缀表达式(逆波兰表示法)**: 后缀表达式是一...
总结,LL1和SLR文法在编译器设计中扮演着核心角色,它们帮助我们理解和解析算术表达式。在VC++环境下实现这些文法,需要理解文法的构造、解析表的生成以及词法和语法分析器的编写,这都是编译原理中的基础实践。通过...
本项目旨在实现一个能够解析并计算算术表达式的软件。具体目标如下: 1. **内容**:该程序应能正确计算含有括号的算术表达式,通过逐步解析并计算括号内的表达式,最终得出整个表达式的值。 - 举例说明:对于...
在解析算术表达式时,通常采用两种主要方法:中缀表达式转换为后缀表达式(逆波兰表示法),以及直接解析后缀表达式。前者涉及将中缀表达式通过操作符优先级规则转换,后者则利用栈来依次处理后缀表达式中的元素。 ...