数学表达式解析(前缀中缀后缀)
前缀、中缀、后缀表达式

前缀、中缀、后缀表达式表达式是数学和计算机科学中常见的概念,用于描述数值计算或逻辑运算。
在表达式中,运算符和操作数以特定的顺序组合在一起,形成一个完整的计算式。
表达式可以使用不同的表示方法,其中包括前缀、中缀和后缀表达式。
前缀表达式,也称为波兰表达式,是由波兰数学家扬·武卡谢维奇首先提出的。
在前缀表达式中,运算符位于操作数之前,这种表示方法非常直观,使得计算机能够更方便地进行运算。
例如,前缀表达式"+ 3 4"表示的是3+4,其中"+"为运算符,而3和4为操作数。
在计算机中,前缀表达式可以通过栈来进行计算,先将操作数入栈,然后按照运算符的顺序进行计算。
中缀表达式是我们常见的数学表达式表示方法,其中运算符位于两个操作数之间。
例如,中缀表达式"3 + 4"表示的是3+4。
在计算机中,中缀表达式需要通过运算符的优先级和括号来确定运算的顺序。
为了方便计算机进行运算,我们可以将中缀表达式转换为前缀或后缀表达式。
后缀表达式,也称为逆波兰表达式,是由澳大利亚计算机科学家查尔斯·鲁瑟福德提出的。
在后缀表达式中,运算符位于操作数之后,这种表示方法更加简洁明了。
例如,后缀表达式"3 4 +"表示的是3+4。
计算机可以通过栈来进行后缀表达式的计算,将操作数入栈,遇到运算符时将栈顶的两个操作数弹出进行运算,再将结果入栈,直到整个表达式计算完毕。
前缀、中缀和后缀表达式在计算机科学中都有各自的应用场景。
前缀表达式适合计算机进行快速计算,特别是对于表达式中含有复杂运算符优先级的情况。
中缀表达式是我们常见的数学表达方式,更加直观易懂,但需要借助运算符优先级和括号来确定计算顺序。
后缀表达式则更加简洁明了,没有括号和优先级的限制,方便计算机进行计算。
在实际应用中,我们可以根据需要选择适合的表达式表示方法。
如果需要对表达式进行计算,尤其是对复杂运算符优先级的表达式进行快速计算,可以选择使用前缀或后缀表达式。
前缀、中缀、后缀表达式

前缀、中缀、后缀表达式在计算机科学中,表达式是由操作符和操作数组成的数学式子。
为了方便计算机进行计算,表达式可以以不同的形式表示,包括前缀、中缀和后缀表达式。
一、前缀表达式前缀表达式,也称为波兰表达式,是将操作符写在操作数之前的一种表达式形式。
例如,加法操作符写在两个操作数之前,减法操作符写在两个操作数之前,以此类推。
前缀表达式的一个特点是,操作符和操作数之间没有括号,而是通过空格或其他分隔符进行分隔。
这种形式的表达式可以直接被计算机解析和计算。
例如,表达式"+ 2 3"可以被解析为2加3,得到结果5。
同样地,表达式"- 5 3"可以被解析为5减去3,得到结果2。
二、中缀表达式中缀表达式是我们平时最常见的表达式形式,操作符位于两个操作数之间。
例如,"2 + 3"就是一个中缀表达式。
中缀表达式的一个特点是使用了括号来表示优先级,以及操作符的结合性。
例如,"(2 + 3) * 4"表示先计算括号内的加法,再将结果乘以4。
中缀表达式的解析和计算相对复杂,需要考虑操作符的优先级和结合性,以及括号的使用。
为了方便计算机进行计算,通常需要将中缀表达式转换为其他形式。
三、后缀表达式后缀表达式,也称为逆波兰表达式,是将操作符写在操作数之后的一种表达式形式。
例如,"2 3 +"就是一个后缀表达式。
后缀表达式的一个特点是,操作符和操作数之间也没有括号,而是通过空格或其他分隔符进行分隔。
这种形式的表达式同样可以直接被计算机解析和计算。
后缀表达式的解析和计算相对简单,不需要考虑操作符的优先级和结合性,也不需要使用括号。
计算机可以通过从左到右依次处理操作数和操作符,最终得到结果。
例如,表达式"2 3 +"可以被解析为2加3,得到结果5。
同样地,表达式"5 3 -"可以被解析为5减去3,得到结果2。
前缀、中缀、后缀表达式

本文将让您从头至尾认识 W3Eval 功能性的要点;您将看到一些用于表达式求值的代码。
不过,我们还是先看看表达式求值的经典算法,这样您就会明白 W3Eval 方法的差异究竟有多少。
表达式求值的经典算法编写代码对算术表达式求值的经典方法由 Donald Knuth 描述于 1962 年(请参阅参考资料)。
Knuth 将此概括为三个步骤:∙对中缀表达式进行语法分析∙中缀表达式到后缀表达式的转换∙对后缀表达式求值注意到我们谈到的这个经典算法有些简化:算术表达式只包含操作数、二元操作符和一种括号。
此外,对于每个操作数和操作符,只用单个字符表示,使语法分析直观。
表达式表示法算术表达式中最常见的表示法形式有中缀、前缀和后缀表示法。
中缀表示法是书写表达式的常见方式,而前缀和后缀表示法主要用于计算机科学领域。
中缀表示法中缀表示法是算术表达式的常规表示法。
称它为中缀表示法是因为每个操作符都位于其操作数的中间,这种表示法只适用于操作符恰好对应两个操作数的时候(在操作符是二元操作符如加、减、乘、除以及取模的情况下)。
对以中缀表示法书写的表达式进行语法分析时,需要用括号和优先规则排除多义性。
前缀表示法前缀表示法中,操作符写在操作数的前面。
这种表示法经常用于计算机科学,特别是编译器设计方面。
为纪念其发明家— Jan Lukasiewicz(请参阅参考资料),这种表示法也称波兰表示法。
后缀表示法在后缀表示法中,操作符位于操作数后面。
后缀表示法也称逆波兰表示法(reverse Polish notation,RPN),因其使表达式求值变得轻松,所以被普遍使用。
前缀和后缀表示法有三项公共特征:∙操作数的顺序与等价的中缀表达式中操作数的顺序一致∙不需要括号∙操作符的优先级不相关中缀表达式到后缀表达式的转换要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式,必须了解操作符的优先级和结合性。
优先级或者说操作符的强度决定求值顺序;优先级高的操作符比优先级低的操作符先求值。
前缀 中缀 后缀表达式 题目

前缀中缀后缀表达式题目摘要:一、前缀表达式的概念与作用1.前缀表达式的定义2.前缀表达式的特点3.前缀表达式在编程中的应用二、中缀表达式的概念与作用1.中缀表达式的定义2.中缀表达式的特点3.中缀表达式在编程中的应用三、后缀表达式的概念与作用1.后缀表达式的定义2.后缀表达式的特点3.后缀表达式在编程中的应用四、题目:比较前缀、中缀、后缀表达式的优缺点1.前缀表达式的优缺点2.中缀表达式的优缺点3.后缀表达式的优缺点正文:一、前缀表达式的概念与作用前缀表达式是一种计算表达式的方式,它将运算符写在表达式的最前面,然后是运算对象。
前缀表达式的优点是便于实现计算的逆序,即从右到左进行计算。
在编程中,前缀表达式常用于实现计算器、文本编辑器等程序。
二、中缀表达式的概念与作用中缀表达式是一种将运算符写在表达式的中间,然后是运算对象的表达式形式。
中缀表达式的优点是便于实现程序的递归,因为在递归过程中,可以很容易地知道当前运算符的优先级。
在编程中,中缀表达式常用于实现编译器、解释器等程序。
三、后缀表达式的概念与作用后缀表达式是一种将运算符写在表达式的最后面,然后是运算对象的表达式形式。
后缀表达式的优点是便于实现计算的顺序,即从左到右进行计算。
在编程中,后缀表达式常用于实现数据结构、算法等课程的相关练习。
四、比较前缀、中缀、后缀表达式的优缺点1.前缀表达式的优点:便于实现计算的逆序,常用于计算器等程序;缺点:不利于实现程序的递归。
2.中缀表达式的优点:便于实现程序的递归,常用于编译器等程序;缺点:不利于实现计算的顺序。
3.后缀表达式的优点:便于实现计算的顺序,常用于数据结构等程序;缺点:不利于实现程序的递归。
综上所述,前缀、中缀、后缀表达式各有优缺点,适用于不同的编程场景。
前缀表达式计算方法

前缀表达式计算方法前缀表达式,也称为波兰表达式,是一种数学表达式的表示方法。
与我们常见的中缀表达式(运算符位于操作数之间)和后缀表达式(运算符位于操作数之后)不同,前缀表达式将运算符置于操作数之前。
本文将介绍前缀表达式的计算方法及其应用。
一、前缀表达式的基本概念前缀表达式是一种无歧义的数学表达式表示方法,它可以通过简单的规则进行计算。
在前缀表达式中,运算符位于操作数之前,每个运算符都与其相应的操作数紧密相连,形成一个完整的表达式。
例如,加法运算符(+)位于操作数2和3之前的前缀表达式为"+ 2 3"。
二、前缀表达式的计算方法前缀表达式的计算方法相对简单,可以通过以下步骤进行:1. 从右至左扫描前缀表达式,遇到操作数则入栈。
2. 遇到运算符,则从栈中弹出两个操作数进行运算,并将结果入栈。
3. 重复步骤2,直到扫描完整个前缀表达式。
4. 栈中最后剩下的元素即为计算结果。
例如,对于前缀表达式"+ * 2 3 4"的计算过程如下:1. 从右至左扫描前缀表达式,首先遇到的是操作数4,将其入栈。
2. 继续扫描,遇到操作数3,将其入栈。
3. 再次扫描,遇到操作数2,将其入栈。
4. 继续扫描,遇到乘法运算符(*),从栈中弹出操作数2和3,计算结果6,并将其入栈。
5. 最后扫描到加法运算符(+),从栈中弹出操作数6和4,计算结果10,并将其入栈。
6. 完成扫描后,栈中剩下的元素10即为计算结果。
三、前缀表达式的应用前缀表达式在计算机科学和数学领域有着广泛的应用。
其中,其主要应用之一是在编译器和解释器中进行数学表达式的计算。
通过将中缀表达式转换为前缀表达式,可以简化计算过程,提高计算效率。
前缀表达式还可以用于构建抽象语法树(Abstract Syntax Tree,AST)。
AST是一种用于表示程序语言结构的树状数据结构,通过前缀表达式可以方便地构建出相应的AST,进而进行语法分析和程序优化。
前中后缀表达式的转化例题

前中后缀表达式的转化例题
摘要:
1.前缀表达式的概念和特点
2.中缀表达式的概念和特点
3.后缀表达式的概念和特点
4.前中后缀表达式的转换方法
5.例题解析
正文:
一、前缀表达式的概念和特点
前缀表达式是一种二叉树表达式,其特点是在二叉树的每个节点前添加一个操作符,然后将操作符和操作数一起作为表达式的一部分。
例如,表达式“A+B”可以表示为二叉树“A,+,B”。
二、中缀表达式的概念和特点
中缀表达式是另一种二叉树表达式,其特点是将操作符放在二叉树的叶子节点,操作数放在操作符的左右子树。
例如,表达式“A+B”可以表示为二叉树“A,+,B”。
三、后缀表达式的概念和特点
后缀表达式也是一种二叉树表达式,其特点是将操作数放在二叉树的叶子节点,操作符放在操作数的后面。
例如,表达式“A+B”可以表示为二叉树“A,+B”。
四、前中后缀表达式的转换方法
前缀表达式、中缀表达式和后缀表达式之间可以相互转换。
其中,前缀表达式和中缀表达式的转换较为简单,通常采用递归或栈的方式实现。
而中缀表达式和后缀表达式的转换通常采用递归或栈的方式实现。
五、例题解析
假设有一个前缀表达式“A,+,B,*,C”,要求将其转换为后缀表达式。
首先,我们需要将前缀表达式转换为中缀表达式,然后再将中缀表达式转换为后缀表达式。
前缀中缀后缀相互转换

前缀中缀后缀相互转换符号说明•为了表示简便,程序中符号如下•¬, 非•∨,或•∧, 与•→, 推出•=, 等价中缀转后缀•例:P∨Q∧R∨(T=S)输出:PQR∧∨TS=∨算法流程:1.初始化两个栈:运算符栈S1,储存中间结果的栈S2;2.从左至右扫描中缀表达式:1.遇到操作数2.遇到运算符3.遇到括号P∨Q∧R∨(T=S)中缀转后缀算法流程:1.初始化两个栈:运算符栈S1,储存中间结果的栈S2;2.从左至右扫描中缀表达式:1.遇到操作数:直接压入S22.遇到运算符3.遇到括号P∨Q∧R∨(T=S)P中缀转后缀算法流程:1.初始化两个栈:运算符栈S1,储存中间结果的栈S2;2.从左至右扫描中缀表达式:1.遇到操作数2.遇到运算符:1.如果S1为空,或S1栈顶为左括号“(”,该运算符压入S1;P∨Q∧R∨(T=S)2.若优先级高于栈顶运算符,该运算符压入S1;3.否则,S1栈顶运算符弹出并压入S2,重新进行2-2操作。
3.遇到括号∨P中缀转后缀算法流程:1.初始化两个栈:运算符栈S1,储存中间结果的栈S2;2.从左至右扫描中缀表达式:1.遇到操作数:直接压入S22.遇到运算符3.遇到括号P∨Q∧R∨(T=S)QP∨中缀转后缀算法流程:1.初始化两个栈:运算符栈S 1,储存中间结果的栈S 2;2.从左至右扫描中缀表达式:1.遇到操作数2.遇到运算符:1.如果S 1为空,或S 1栈顶为左括号“(”,该运算符压入S 1;2.若优先级高于栈顶运算符,该运算符压入S 1;3.否则,S 1栈顶运算符弹出并压入S 2,重新进行2-2操作。
3.遇到括号P ∨Q ∧R ∨(T =S)P ∨Q ∧中缀转后缀算法流程:1.初始化两个栈:运算符栈S 1,储存中间结果的栈S 2;2.从左至右扫描中缀表达式:1.遇到操作数:直接压入S 22.遇到运算符:3.遇到括号P ∨Q ∧R ∨(T =S)P ∨Q ∧R中缀转后缀算法流程:1.初始化两个栈:运算符栈S 1,储存中间结果的栈S 2;2.从左至右扫描中缀表达式:1.遇到操作数2.遇到运算符:1.如果S 1为空,或S 1栈顶为左括号“(”,该运算符压入S 1;2.若优先级高于栈顶运算符,该运算符压入S 1;3.否则,S 1栈顶运算符弹出并压入S 2,重新进行2-2操作。
C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这⼀篇就够了⼀、种类介绍算术表达式有三种:前缀表达式、中缀表达式和后缀表达式。
⼀般⽤的是中缀,⽐如1+1,前后缀就是把操作符移到前⾯和后⾯,下⾯简单介绍⼀下这三种表达式。
1、前缀表⽰法前缀表⽰法⼜叫波兰表⽰法,他的操作符置于操作数的前⾯(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引⼊的,⽤于简化命题逻辑。
因为我们⼀般认为操作符是在操作数中间的,所以在⽇常⽣活中⽤的不多,但在计算机科学领域占有⼀席之地。
⼀般的表⽰法对计算机来说处理很⿇烦,每个符号都要考虑优先级,还有括号这种会打乱优先级的存在,将使计算机花费⼤量的资源进⾏解析。
⽽前缀表⽰法没有优先级的概念,他是按顺序处理的。
举个例⼦:9-2*3这个式⼦,计算机需要先分析优先级,先乘后减,找到2*3,再进⾏减操作;化成前缀表⽰法就是:- 9 * 2 3,计算机可以依次读取,操作符作⽤于后⼀个操作数,遇到减就是让9减去后⾯的数,⽽跟着9的是乘,也就是说让9减去乘的结果,这对计算机来说很简单,按顺序来就⾏了。
2、中缀表⽰法这也就是我们⼀般的表⽰法,他的操作符置于操作数的中间(例:1 + 2),前⾯也说过这种⽅法不容易被计算机解析,但他符合⼈们的普遍⽤法,许多编程语⾔也就⽤这种⽅法了。
在中缀表⽰法中括号是必须有的,要不然运算顺序会乱掉。
3、后缀表⽰法后缀表⽰法⼜叫逆波兰表⽰法,他的操作符置于操作数的后⾯(例:1 2 +),他和前缀表⽰法都对计算机⽐较友好,但他很容易⽤堆栈解析,所以在计算机中⽤的很多。
他的解释过程⼀般是:操作数⼊栈;遇到操作符时,操作数出栈,求值,将结果⼊栈;当⼀遍后,栈顶就是表达式的值。
因此逆波兰表达式的求值使⽤堆栈结构很容易实现,且能很快求值。
注意:逆波兰记法并不是简单的波兰表达式的反转。
因为对于不满⾜交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法/ 6 3的逆波兰记法是6 3 /⽽不是3 6 /;数字的数位写法也是常规顺序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。
它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。
举例:(3 + 4) × 5 - 6 就是中缀表达式- × + 3 4 5 6 前缀表达式3 4 + 5 × 6 - 后缀表达式中缀表达式(中缀记法)中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。
中缀表达式是人们常用的算术表示方法。
虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。
对计算机来说,计算前缀或后缀表达式的值非常简单。
前缀表达式(前缀记法、波兰式)前缀表达式的运算符位于操作数之前。
前缀表达式的计算机求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。
例如前缀表达式“- × + 3 4 5 6”:(1) 从右至左扫描,将6、5、4、3压入堆栈;(2) 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;(3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;(4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。
可以看出,用计算机计算前缀表达式的值是很容易的。
将中缀表达式转换为前缀表达式:遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从右至左扫描中缀表达式;(3) 遇到操作数时,将其压入S2;(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;(5) 遇到括号时:(5-1) 如果是右括号“)”,则直接压入S1;(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;(6) 重复步骤(2)至(5),直到表达式的最左边;(7) 将S1中剩余的运算符依次弹出并压入S2;(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
后缀表达式(后缀记法、逆波兰式)后缀表达式与前缀表达式类似,只是运算符位于操作数之后。
后缀表达式的计算机求值:与前缀表达式类似,只是顺序是从左至右:从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
例如后缀表达式“3 4 + 5 × 6 -”:(1) 从左至右扫描,将3和4压入堆栈;(2) 遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈;(3) 将5入栈;(4) 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;(5) 将6入栈;(6) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。
将中缀表达式转换为后缀表达式:与转换为前缀表达式相似,遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从左至右扫描中缀表达式;(3) 遇到操作数时,将其压入S2;(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;(5) 遇到括号时:(5-1) 如果是左括号“(”,则直接压入S1;(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;(6) 重复步骤(2)至(5),直到表达式的最右边;(7) 将S1中剩余的运算符依次弹出并压入S2;(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
编写Java程序将一个中缀表达式转换为前缀表达式和后缀表达式,并计算表达式的值。
其中的toPolishNotation()方法将中缀表达式转换为前缀表达式(波兰式)、toReversePolishNotation()方法则用于将中缀表达式转换为后缀表达式(逆波兰式):注:(1) 程序很长且注释比较少,但如果将上面的理论内容弄懂之后再将程序编译并运行起来,还是比较容易理解的。
有耐心的话可以研究一下。
(2) 此程序是笔者为了说明上述概念而编写,仅做了简单的测试,不保证其中没有Bug,因此不要将其用于除研究之外的其他场合。
[java]view plain copy1.package qmk.simple_test;2.import ;3.import ;4./**5. * Example of converting an infix-expression to6. * Polish Notation (PN) or Reverse Polish Notation (RPN).7. * Written in 2011-8-258. * @author QiaoMingkui9. */10.p ublic class Calculator {11.public static final String USAGE = "== usage ==\n"12. + "input the expressions, and then the program "13. + "will calculate them and show the result.\n"14. + "input 'bye' to exit.\n";15./**16. * @param args17. */18.public static void main(String[] args) {19. ;20. Scanner scanner = new Scanner(System.in);21. String input = "";22.final String CLOSE_MARK = "bye";23."input an expression:");24. input = scanner.nextLine();25.while (input.length() != 026. && !CLOSE_MARK.equals((input))) {27."Polish Notation (PN):");28.try {29. toPolishNotation(input);30. } catch (NumberFormatException e) {31."\ninput error, not a number.");32. } catch (IllegalArgumentException e) {33."\ninput error:" + e.getMessage());34. } catch (Exception e) {35."\ninput error, invalid expression.");36. }37."Reverse Polish Notation (RPN):");38.try {39. toReversePolishNotation(input);40. } catch (NumberFormatException e) {41."\ninput error, not a number.");42. } catch (IllegalArgumentException e) {43."\ninput error:" + e.getMessage());44. } catch (Exception e) {45."\ninput error, invalid expression.");46. }47."input a new expression:");48. input = scanner.nextLine();49. }50."program exits");51. }52./**53. * parse the expression , and calculate it.54. * @param input55. * @throws IllegalArgumentException56. * @throws NumberFormatException57. */58.private static void toPolishNotation(String input)59.throws IllegalArgumentException, NumberFormatException {60.int len = input.length();61.char c, tempChar;62. Stack<Character> s1 = new Stack<Character>();63. Stack<Double> s2 = new Stack<Double>();64. Stack<Object> expression = new Stack<Object>();65.double number;66.int lastIndex = -1;67.for (int i=len-1; i>=0; --i) {68. c = input.charAt(i);69.if (Character.isDigit(c)) {70. lastIndex = readDoubleReverse(input, i);71. number = Double.parseDouble(input.substring(lastIndex, i+1));72. s2.push(number);73. i = lastIndex;74.if ((int) number == number)75. expression.push((int) number);76.else77. expression.push(number);78. } else if (isOperator(c)) {79.while (!s1.isEmpty()80. && s1.peek() != ')'81. && priorityCompare(c, s1.peek()) < 0) {82. expression.push(s1.peek());83. s2.push(calc(s2.pop(), s2.pop(), s1.pop()));84. }85. s1.push(c);86. } else if (c == ')') {87. s1.push(c);88. } else if (c == '(') {89.while ((tempChar=s1.pop()) != ')') {90. expression.push(tempChar);91. s2.push(calc(s2.pop(), s2.pop(), tempChar));92.if (s1.isEmpty()) {93.throw new IllegalArgumentException(94."bracket dosen't match,missing right bracket ')'.");95. }96. }97. } else if (c == ' ') {98.// ignore99. } else {100.throw new IllegalArgumentException( 101."wrong character '" + c + "' ");102. }103. }104.while (!s1.isEmpty()) {105. tempChar = s1.pop();106. expression.push(tempChar);107. s2.push(calc(s2.pop(), s2.pop(), tempChar)); 108. }109.while (!expression.isEmpty()) {110. + " ");111. }112.double result = s2.pop();113.if (!s2.isEmpty())114.throw new IllegalArgumentException("input is a wrong expression.");115. ;116.if ((int) result == result)117."the result is " + (int) result);118.else119."the result is " + result);120. }121./**122. * parse the expression, and calculate it.123. * @param input124. * @throws IllegalArgumentException125. * @throws NumberFormatException126. */127.private static void toReversePolishNotation(String input)128.throws IllegalArgumentException, NumberFormatE xception {129.int len = input.length();130.char c, tempChar;131. Stack<Character> s1 = new Stack<Character>(); 132. Stack<Double> s2 = new Stack<Double>();133.double number;134.int lastIndex = -1;135.for (int i=0; i<len; ++i) {136. c = input.charAt(i);137.if (Character.isDigit(c) || c == '.') { 138. lastIndex = readDouble(input, i); 139. number = Double.parseDouble(input.substr ing(i, lastIndex));140. s2.push(number);141. i = lastIndex - 1;142.if ((int) number == number)143. number + " ");144.else145. + " ");146. } else if (isOperator(c)) {147.while (!s1.isEmpty()148. && s1.peek() != '('149. && priorityCompare(c, s1.pee k()) <= 0) {150. + " ");151.double num1 = s2.pop();152.double num2 = s2.pop();153. s2.push(calc(num2, num1, s1.pop()) );154. }155. s1.push(c);156. } else if (c == '(') {157. s1.push(c);158. } else if (c == ')') {159.while ((tempChar=s1.pop()) != '(') { 160. + " ");161.double num1 = s2.pop();162.double num2 = s2.pop();163. s2.push(calc(num2, num1, tempChar) );164.if (s1.isEmpty()) {165.throw new IllegalArgumentExc eption(166."bracket dosen't match , missing left bracket '('.");167. }168. }169. } else if (c == ' ') {170.// ignore171. } else {172.throw new IllegalArgumentException( 173."wrong character '" + c + "' ");174. }175. }176.while (!s1.isEmpty()) {177. tempChar = s1.pop();178. + " ");179.double num1 = s2.pop();180.double num2 = s2.pop();181. s2.push(calc(num2, num1, tempChar));182. }183.double result = s2.pop();184.if (!s2.isEmpty())185.throw new IllegalArgumentException("input is a wrong expression.");186. ;187.if ((int) result == result)188."the result is " + (int) result);189.else190."the result is " + result);191. }192./**193. * calculate the two number with the operation.194. * @param num1195. * @param num2196. * @param op197. * @return198. * @throws IllegalArgumentException199. */200.private static double calc(double num1, double num2, char op)201.throws IllegalArgumentException {202.switch (op) {203.case'+':204.return num1 + num2;205.case'-':206.return num1 - num2;207.case'*':208.return num1 * num2;209.case'/':210.if (num2 == 0) throw new IllegalArgumentExcept ion("divisor can't be 0.");211.return num1 / num2;212.default:213.return0; // will never catch up here214. }215. }216./**217. * compare the two operations' priority.218. * @param c219. * @param peek220. * @return221. */222.private static int priorityCompare(char op1, char op2) { 223.switch (op1) {224.case'+': case'-':225.return (op2 == '*' || op2 == '/' ? -1 : 0); 226.case'*': case'/':227.return (op2 == '+' || op2 == '-' ? 1 : 0); 228. }229.return1;230. }231./**232. * read the next number (reverse)233. * @param input234. * @param start235. * @return236. * @throws IllegalArgumentException237. */238.private static int readDoubleReverse(String input, int sta rt)239.throws IllegalArgumentException {240.int dotIndex = -1;241.char c;242.for (int i=start; i>=0; --i) {243. c = input.charAt(i);244.if (c == '.') {245.if (dotIndex != -1)246.throw new IllegalArgumentException (247."there have more than 1 dots in the number.");248.else249. dotIndex = i;250. } else if (!Character.isDigit(c)) {251.return i + 1;252. } else if (i == 0) {253.return0;254. }255. }256.throw new IllegalArgumentException("not a number.");257. }258./**259. * read the next number260. * @param input261. * @param start262. * @return263. * @throws IllegalArgumentException264. */265.private static int readDouble(String input, int start) 266.throws IllegalArgumentException {267.int len = input.length();268.int dotIndex = -1;269.char c;270.for (int i=start; i<len; ++i) {271. c = input.charAt(i);272.if (c == '.') {273.if (dotIndex != -1)274.throw new IllegalArgumentException (275."there have more than 1 dots in the number.");276.else if (i == len - 1)277.throw new IllegalArgumentException (278."not a number, dot can't be the la st part of a number.");279.else280. dotIndex = i;281. } else if (!Character.isDigit(c)) {282.if (dotIndex == -1 || i - dotIndex > 1)283.return i;284.else285.throw new IllegalArgumentException (286."not a number, dot can't be the la st part of a number.");287. } else if (i == len - 1) {288.return len;289. }290. }291.throw new IllegalArgumentException("not a number.");292. }293./**294. * return true if the character is an operator.295. * @param c296. * @return297. */298.private static boolean isOperator(char c) {299.return (c=='+' || c=='-' || c=='*' || c=='/');300. }301.}下面是程序运行结果(绿色为用户输入):== usage ==input the expressions, and then the program will calculate them and show the result. input 'bye' to exit.input an expression:3.8+5.3Polish Notation (PN):+ 3.8 5.3the result is 9.1Reverse Polish Notation (RPN):3.8 5.3 +the result is 9.1input a new expression:5*(9.1+3.2)/(1-5+4.88)Polish Notation (PN):/ * 5 + 9.1 3.2 + - 1 5 4.88the result is 69.636364Reverse Polish Notation (RPN):5 9.1 3.2 + * 1 5 - 4.88 + /the result is 69.636364input a new expression:1+((2+3)*4)-5Polish Notation (PN):- + 1 * + 2 3 4 5the result is 16Reverse Polish Notation (RPN):1 2 3 + 4 * + 5 -the result is 16input a new expression:byeprogram exits。