20165235结对编程练习_四则运算(第一周)整数/多运算符

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>();其中一个存储操作符号,一个存储数值。

具体分析程序

  1. 在main方法中传入String类数据:((5*7+6)-1)/2#其中#是结束标志符,当signStack的栈顶数据为#时运算结束。
  2. 将从main方法中的String 类数据传入caculate(String str)方法中去。在此函数中首先声明两个StringBuffer类对象:tempNum ;用来临时存放数字字符串(当为多位数时) string = new StringBuffer().append(str),将传入的数值追加在string中。在声明一个Stringtemp然后通过substring(0, 1)把截取到的第一个字符传入temp中。通过isNum方法判断temp中的字符是否是操作符,如果不是则把temp中的数字赋值给tempNum。如果是,再接着判断是否是(,如果是就将tempNum中的数字赋值给int 类型的um,并把num压入numStack中,同时把tempNum中的数据删除。接着用当前取得的运算符与栈顶运算符比较优先级:若高于,则因为会先运算,将运算结果result压入numStack栈顶(运算通过switch语句进行);若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算,若小于,则同理,取出栈顶元素运算,将结果入操作数栈。若temp中取到的字符是#,就会进行弹栈。
  3. 以上就是主要的流程,不停的循环,每次循环把str中的第一个字符存入temp中然后进行以上环节。

Junit测试:

这里我只测试一组正常情况,对于float类型的数据还是无法运算,改起来也有一定的难度,没能完成这项任务。还有因为这个程序是在一个类中完成,所以也没有画MUL图。

功能截图:

代码链接

结对感受:

结对编程就是俩人在一起分析代码的过程,本次我借鉴了网上大佬分享的代码,直接写估计有点难。但我是在完全看懂代码并且敲了一遍代码的情况下提交的此次作业。因为对堆栈不是很了解,所以本次结对编程还是有许多不懂的地方,但是通过网络等解决了问题。在异常情况,边界情况的处理上不是很到位,希望可以在下周的作业中完成的更出色。

结对编程的照片

参考材料

原文地址:https://www.cnblogs.com/qy20165235/p/8849718.html