项目设计
1项目总体框架
2系统详细设计
2.2.1 Start.java
程序入口
2.2.2Calculator.java
1)继承JFram,实现ActionListener,这样不用再单独写监听事件
2)构造方法:画界面
3)actionPerformed 重写的监听实践的方法
2.2.3 Utils.java
CalculatorWindow类:operation内部类,用来返回运算符的大小(优先级)
2.3关键算法分析
算法实现总流程:
将一个String字符串转变成一个List集合
将得到的List集合也就是中缀表达式装换成后缀表达式
计算后缀表达式
2.3.1中缀表达式转后缀表达式
·具体算法
定义一个数组用来保存运算符号
2)定义内部类,用来返回运算符的优先级
3)从左向右扫描表达式:
① 若是操作数:直接输出到后缀表达式中。
② 若是运算符:
a. 栈为空:直接入栈。
b. 运算符为“)”:依次出栈,直到遇到“(”,“(”出栈并舍弃。
c. 优先级低于或等于栈顶运算符:在遇到“(”和比自己优先级小的运算符之前,将栈顶依次出栈,并输出到后缀表达式中,最后再将该运算符压入栈。
d. 优先级高于栈顶运算符:直接入栈。
4)表达式遍历结束,栈中剩余字符依次出栈,并输出到后缀表达式。
·举例说明
假设中缀表达式:a+(b-c/d)*e
1)扫描操作数a,直接输出到后缀表达式。
后缀表达式:a,栈为空
2)扫描运算符+ :入栈。
a. 后缀表达式:a
b. 栈:
运算符栈 | 栈顶 |
+ | ⬅ |
3)扫描运算符 ( ,优先级大于+,入栈。
a. 后缀表达式:a
b. 栈:
运算符栈 | 栈顶 |
( | ⬅ |
+ |
|
4)扫描操作数b,直接输出到后缀表达式。
a. 后缀表达式:ab
b. 栈不变
5)扫描运算符 - ,括号中的-优先级大,入栈。
a. 后缀表达式:ab
b. 栈:
运算符栈 | 栈顶 |
– | ⬅ |
( |
|
+ |
|
6)扫描操作数c,直接输出到后缀表达式。
a. 后缀表达式:abc
b. 栈不变
7)扫描运算符 / ,优先级大于-,入栈。
a. 后缀表达式:abc
b. 栈:
运算符栈 | 栈顶 |
/ | ⬅ |
– |
|
( |
|
+ |
|
8)扫描操作数d,直接输出到后缀表达式。
a. 后缀表达式:abcd
b. 栈不变
9)扫描运算符 ) ,栈顶运算符依次出栈并输出到后缀表达式,直至 ( 出栈。
a. 后缀表达式:abcd/-
b. 栈:
运算符栈 | 栈顶 |
+ | ⬅ |
10)扫描运算符 * ,优先级大于 + ,入栈。
a. 后缀表达式:abcd/-
b. 栈:
运算符栈 | 栈顶 |
* | ⬅ |
+ |
|
11)扫描操作数e,直接输出到后缀表达式。
a. 后缀表达式:abcd/-e
b. 栈不变
12)表达式扫描结束,栈顶运算符依次出栈并输出到后缀表达式中。
后缀表达式:abcd/-e*+,栈为空
此时,中缀表达式已转换为后缀表达式,结果为abcd/-e*+
2.3.2后缀表达式求值
·具体算法
1)设置一个栈来存放操作数。
2)从左向右依次扫描后缀表达式:
① 若是操作数:入栈。
② 若是运算符:将两个操作数出栈,计算它们的值,再把结果入栈。
3)重复上述步骤,直至表达式结束,栈中最后一个元素就是后缀表达式的值。
·举例说明
假设后缀表达式:abcd/-e*+
1)扫描操作数abcd,并依次入栈。
操作数栈 | 栈顶 |
d | ⬅ |
c |
|
b |
|
a |
|
2)扫描到运算符 / ,d出栈,c出栈,计算c/d,再重新压入栈。
操作数栈 | 栈顶 |
c/d | ⬅ |
b |
|
a |
|
3)扫描到运算符 - ,c/d出栈,b出栈,计算b-c/d,再重新压入栈。
操作数栈 | 栈顶 |
b-c/d | ⬅ |
a |
|
4)扫描操作数e,入栈。
操作数栈 | 栈顶 |
e | ⬅ |
b-c/d |
|
a |
|
5)扫描到运算符 * ,e出栈,b-c/d出栈,计算 (b-c/d)*e,再重新压入栈。
操作数栈 | 栈顶 |
(b-c/d)*e | ⬅ |
a |
|
6)扫描到运算符 + ,(b-c/d)*e出栈,a出栈,计算 a+(b-c/d)*e ,再重新压入栈。
操作数栈 | 栈顶 |
a+(b-c/d)*e | ⬅ |
此时栈顶的值就是后缀表达式abcd/-e*+的值。