`

计算器制作JAVA版(第三步,表达式求值(+-*/))

阅读更多

这个东西一直是大家关注的热点,也是这个题目的真正目标所在,希望大家能够好好学习了解这个部分的思路想法。虽然这个思路不是以后编译原理上面的标准思路,也不是什么正统方法,但是它确实符合大家的想法和一贯的思路。因为不够正统和强悍,如有高人敬请指点。
那么我们来考虑一下这个表达式,如果只有加减运算符大家是否感觉能很好的解决呢?
首先是单位的数字和运算符(只有加减),那么我们就只用顺序处理即可。形如:a+b-c+d,我们是如何计算的呢?首先计算a+b,然后将结果e替代a+b-->e-c+d-->h+d-->i一次一次计算替换的反复。如此以来我们就有了一个思路,拿出三个,计算结果丢进去,再拿出三个计算。我们假设,这个表达式已经切割好了,放在一个栈(第二步有讲)里面,我们通过对栈操作实现全部运算。

first : =  pop()
while     stack is not empty
    
do        operator : =  pop()
               second    :
=  pop()
               res            :
=   first    < operator >   second
               push(res)
               first          :
=   pop()
return  first

以上的计算是基于:运算符优先级一样,格式正确。剩下的就是来切割解析这个表达式使之成为这种结构。我们只需要一直解析这个字符串,如果出现,标点则前面的就是一个数,我们将它压入栈中。就是类似的方法喽。

p: = ""
n:
= 1
while    n <= length[expression]
        
do       if    expression[n] is the operator
                       then     
if    not   p = ""
                                          then   push(p)
                                                      p=""
                                    push(expression[n])
                       
else       p: = p + expression[n]
                 n:
= n + 1
return  stack


好了,我们现在是同优先级的没有问题了,如果有高优先级的怎么办呢?
如果只考虑+-*/那么只要是*/号出现就可以对其操作符左右的数据进行运算了。也就是说在上面的伪代码里面我们需要加一步判断operator是否为*/的情况,然后进行运算。但是如果我们只扫描到operator就要运算,对于一个双目运算符来说还差一边啊,那么我们能否将这个判断推迟到压入数字的时候进行呢?这样我们需要在压入数据的时候提出前面的若干项进行处理了。

p: = ""
n:
= 1
while    n <= length[expression]
        
do       if    expression[n] is the operator
                       then     
if    not   p = ""
                                          then   
                                                     
// Be careful
                                                     operator : =  pop()
                                                     
if     operator is the  *   or  /
                                                            then  
                                                                    first :
=  pop()
                                                                    second :
= p
                                                                    p:
=  first  < operator >  second
                                                     push(p)
                                                     p
= ""
                                    push(expression[n])
                       
else       p: = p + expression[n]
                 n:
= n + 1
return  stack

如此以来我们实现了+-*/了,HOHO 不错吧,思路就是这样一步一步来的。

下面我们想加入括号了,现在我们继续想,其实括号就是更高的一层优先级了,由于基于以上的运算处理,在括号“缝合”(即碰到了')')的时候括号里面只有加减法,也就是说刚刚的栈处理结束标志是表达式末尾开始的标志就是表达式开头,而这里的开头是‘(’结尾是‘)’,还有什么区别吗?其实没什么了,那么我们按照这个思路,如果expression[n]是括号,‘(’压入栈中,')'开始运算将结果压入栈中。这样看似乎不难哦。

p: = ""
n:
= 1
while    n <= length[expression]
        
do       if    expression[n] is the operator
                       then     
if    not   p = ""
                                          then   
                                                     
// Be careful
                                                     operator : =  pop()
                                                     
if     operator is the  *   or  /
                                                            then  
                                                                    first :
=  pop()
                                                                    second :
= p
                                                                    p:
=  first  < operator >  second
                                                     push(p)
                                                     p
= ""
                                    push(expression[n])
                       elseif   expression[n] is the bracket ( or )
                                   then
                                           
if   expression[n] = " ( "
                                               then push(expression[n])
                                               
else   res:=compute the expression between the  " ( "  and  " ) "
                                                         //Push the result
                                                         push(res)
    
                       
else       p: = p + expression[n]
                 n:
= n + 1
return  stack

这样看似乎很爽啊,但是大家看看这个表达式  1+(2+3*4)*(5+6)
计算结果是 165  而不是正确结果 155.为什么呢?
因为我们在计算之后直接压入栈中而忽略了前面的那个*号。至此我们应该知道,一旦压入数据就得检查前面的operator.
这样以来我们需要对push(object)单独再包装一下,使它明白只要压入就得检查.

至此我们已经知道了基本的运算体系。
在实际编码过程中,大家可能要碰到大量的边界讨论问题,这一定要小心。
关于乘方和小数问题我将尽快写出来。

分享到:
评论

相关推荐

    Linux命令术语全称

    17. **awk="Aho Weiberger and Kernighan" 三个作者的姓的第一个字母** - **含义**:一种文本处理工具。 - **用途**:执行强大的文本处理任务。 18. **bash=Bourne Again SHell 记一个shell足已** - **含义**:...

    一个简单的安卓计算器

    - **操作状态**:计算器需要跟踪当前的运算状态,是等待输入第一个数,还是等待第二个数,或者正在进行运算。 - **计算结果**:结果通常保存在一个变量中,并在每次操作后更新。 6. **错误处理** - **除零错误**...

    Linux_UNIX 下的命令大全

    **3. adb** - **功能**:汇编语言调试工具。 - **用法**:`adb [选项] 文件` - **说明**:主要用于调试汇编语言编写的程序。 **4. admin** - **功能**:创建和管理SCCS(Source Code Control System)文件。 - **...

    python基础练习题

    - **任务说明**:将两个文件中的内容按字母顺序合并到第三个文件中。 - **实现流程**:读取文件内容、排序、写入新文件。 - **文件操作**:涉及文件读写操作。 #### 13. 用户登录验证 - **验证逻辑**:用户名为...

    fx-7400说明书

    - **功能键介绍**:了解计算器上各个按键的功能是非常重要的第一步。例如,`AC`键用于清除屏幕上的内容,`MODE`键用于切换不同的计算模式等。 - **特殊功能键**:某些键可能具有多重功能,通过结合`SHIFT`或`ALPHA`...

    2021-2022计算机二级等级考试试题及答案No.12328.docx

    #### 3. J2EE Model II 模式中的模型层对象 **知识点概述:** - **J2EE简介:**J2EE(Java 2 Platform, Enterprise Edition)是一套企业级Java平台标准,主要用于开发和部署可移植、健壮、可伸缩且安全的多层Web...

    2021-2022计算机二级等级考试试题及答案No.3923.docx

    - **解释**:发布控件通常不属于开发环境的标准组件,而是第三方工具或特定框架的一部分。 ### 7. 文件恢复 如果已清空回收站,则无法恢复被删除的文件。 - **解释**:当文件从回收站中删除时,它们会被永久删除...

    C#制作一个简单计算器程序

    这个程序是基于“Visual C# .NET 应用教程第二版”的课后练习题,旨在帮助学习者掌握C#的基础语法和控制流程,同时理解面向对象编程的基本概念。 首先,我们需要了解C#语言的基础知识。C#是一种面向对象的编程语言...

    使用Android Studio开发的基于java实现的计算器APP

    14. **发布流程**:完成开发后,应用需要打包成APK并签名,然后可以通过Google Play或其他第三方应用市场发布。 综上所述,"CalculatorXingFeifei"项目涵盖了Android应用开发的核心概念和技术,包括Android Studio...

    C#制作的计算器(实现了加减乘除的先后运算)

    1. **用户界面**:创建计算器的第一步是设计用户界面。这通常包括数字按钮(0-9),运算符按钮(+,-,*,/),等于号按钮,以及可能的清除和退格按钮。在C#中,我们可以使用Windows Forms或WPF来构建这样的图形用户...

    完美版JS计算器--内置文档说明

    这个计算器是制作者在其编程学习旅程的第四阶段完成的作品,因此我们可以预期它涵盖了JavaScript(JS)的一些核心概念和高级特性。 首先,让我们聚焦于JavaScript的基础部分。JS是一种广泛用于网页和网络应用的脚本...

    javascript

    3. **计算与显示结果**: 将两个数值相加, 并将结果设置为第三个文本框的值。 #### 十三、输入验证与计算 1. **验证输入**: 使用 `isNaN` 函数来检查输入是否为数字, 使用 `parseInt` 或 `parseFloat` 获取数值。 2...

    可以进行简易表达式计算的C++程序

    1. **词法分析**:这是程序的第一步,它将输入的字符串分解成一个个称为“标记”(tokens)的单位。例如,“2 + 3 * 4”会被分解为数字2、操作符+、数字3、操作符* 和数字4。括号也需要被识别为特殊的标记。 2. **...

    NOC - kitten - 综合练习 四模拟题附答案

    **题目描述**:编程猫制作了一个“取整计算器”,如果输入数字“10.9”,新建对话框会输出什么? - **知识点**: - 取整操作的理解 - 数字输入与处理 - 对话框显示结果的方法 **解析**: 在Scratch中,取整通常...

    Object-C语言教程&案例&相关项目资源分享.docx

    - **《Objective-C 编程(第 2 版)》**:这是一本非常适合初学者的书籍,通过大量的实例和练习,逐步介绍了Objective-C的基本概念和技术。 - **《Cocoa编程指南》**:这本书主要介绍Cocoa框架的使用方法,对于希望...

    jsp开发讲义

    2. **JSP表达式**:将表达式的结果显示在页面中。 ```jsp () %&gt; ``` 3. **JSP声明**:用于声明变量和方法。 ```jsp ! int sum(int num1, int num2) { return num1 + num2; } %&gt; ``` ##### 注释 1. **...

    MFC计算器制作

    下面,我们将会详细讲解MFC计算器制作的关键知识点,包括界面设计、事件处理、数学函数实现以及MFC框架的基本用法。 1. **MFC框架基础**: MFC 是基于面向对象编程思想的,它将Windows API的许多功能封装成类,如...

Global site tag (gtag.js) - Google Analytics