20165235结对编程练习_四则运算(第一周)整数/多运算符
需求分析
对于四则运算,本次实验需要用到堆栈,所以首先有必要了解一下堆栈:堆栈是一种“先进后出”的数据结构,只能在一端进行输入输出。堆栈把第一个放入该堆栈的数据放在最低下,而把后续放入的数据放在已有数据的顶上。向堆栈中输入数据的操作称为“压栈”,从堆栈中输出数据称之为“弹栈”。由于堆栈总是在顶端进行数据的输入输出操作,所以弹栈总是输出(删除)最后一个压入的数据。
使用java.util包中的Stack
public E push(E item)
压栈操作public E pop()
弹栈操作public boolean empty()
判断堆栈中是否有数据public E peek()
获取堆栈顶端的数据,但不删除public int search (Object data)
获取数据在堆栈中的位置,最顶端是1,向下依次增加。
中缀表达式:即人们常用的算式写法,如8+(9-1)*8+7/2
,后缀表达式:运算符放到数字后,如8 9 1 - 8 * + 7 2 /+
-
1.中缀表达式转后缀表达式:
-
从左到右遍历中缀表达式的每一个数字和运算符。
-
如果数字就输出(即存入后缀表达式);
-
如果是右括号,则弹出左括号之前的运算符;
-
如果优先级低于栈顶运算符,则弹出栈顶运算符,并将当前运算符进栈。
-
遍历结束后,将栈则剩余运算符弹出。
-
2.后缀表达式计算结果
从左到右遍历后缀表达式,遇到数字就进栈,遇到符号,就将栈顶的两个数字出栈运算,运算结果进栈,直到获得最终结果。
设计思路:
利用栈,进行四则运算的类
- 用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack,一个用来保存计算优先符signStack
- 基本算法实现思路为:用当前取得的运算符与signStack栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;
- 若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;
- 若小于,则同理,取出栈顶元素运算,将结果压入操作数栈。各个优先级'(' > '*' = '/' > '+' = '-' > ')'
- 在本次程序中只设计了一个类,在类中实现了多个方法:
private boolean isNum(String temp)
判断传入的字符是不是0-9的数字private boolean compare(char str)
比较运算符的优先级。public int caculate(String str)
对传入的值进行计算。在此方法中声明了两个堆栈:private Stack<Character> signStack = new Stack<Character>();
,
private Stack<Integer> numStack = new Stack<Integer>();
其中一个存储操作符号,一个存储数值。
具体分析程序
- 在main方法中传入String类数据:
((5*7+6)-1)/2#
其中#
是结束标志符,当signStack的栈顶数据为#时运算结束。 - 将从
main
方法中的String
类数据传入caculate(String str)
方法中去。在此函数中首先声明两个StringBuffer
类对象:tempNum
;用来临时存放数字字符串(当为多位数时)string = new StringBuffer().append(str)
,将传入的数值追加在string
中。在声明一个String
类temp
然后通过substring(0, 1)
把截取到的第一个字符传入temp
中。通过isNum
方法判断temp
中的字符是否是操作符,如果不是则把temp
中的数字赋值给tempNum
。如果是,再接着判断是否是(
,如果是就将tempNum
中的数字赋值给int
类型的um
,并把num
压入numStack
中,同时把tempNum
中的数据删除。接着用当前取得的运算符与栈顶运算符比较优先级:若高于,则因为会先运算,将运算结果result
压入numStack
栈顶(运算通过switch
语句进行);若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算,若小于,则同理,取出栈顶元素运算,将结果入操作数栈。若temp
中取到的字符是#,就会进行弹栈。 - 以上就是主要的流程,不停的循环,每次循环把
str
中的第一个字符存入temp
中然后进行以上环节。
Junit测试:
这里我只测试一组正常情况,对于float类型的数据还是无法运算,改起来也有一定的难度,没能完成这项任务。还有因为这个程序是在一个类中完成,所以也没有画MUL图。
功能截图:
代码链接
结对感受:
结对编程就是俩人在一起分析代码的过程,本次我借鉴了网上大佬分享的代码,直接写估计有点难。但我是在完全看懂代码并且敲了一遍代码的情况下提交的此次作业。因为对堆栈不是很了解,所以本次结对编程还是有许多不懂的地方,但是通过网络等解决了问题。在异常情况,边界情况的处理上不是很到位,希望可以在下周的作业中完成的更出色。