一.结对对象
- 姓名:侯泽洋
- 学号:20172308
- 担任角色:驾驶员(侯泽洋)
- 伙伴第二周博客地址
二.本周内容
(一)继续编写上周未完成代码
1.本周继续编写代码,使代码支持分数类计算
2.相关过程截图
a.下图是上周编写的生成题目的类,不能运行。
下图是本周更新的代码,可以支持分数的产生,红色框内为主要更改区域
b.下图是代码中题目转后缀表达式的部分代码及运行结果截图
c.下图是代码中后缀表达式计算结果的部分代码及运行结果截图
3.关键代码解释
在题目中生成真分数及包含真分数的题目转换为后缀表达式
- 生成真分数:这里我们让产生的随机数含有复数,举例,我们产生-4~9之间的随机数,如果产生随机数为负数,就将一个随机产生的真分数赋给一个String型的figure,如果产生的随机数为0~9,则将此随机数转换为String型的赋给figure,这样就完成了真分数的生成在题目中。
- 含真分数的题目转后缀表达式:我们调用StringTokenizer类中的方法,将上面的题目转换为StringTokenizer类的一个对象,然后使用nextToken()方法,将其分为String的字符串,然后判断字符串的长度,如果字符串长度大于1,就将字符串直接输出,然后下面就是字符串为1的,包括整数和操作符,这个在上周已经解决,包括入栈出栈,都已解决。
- 后缀表达式求值:正在编写中:将所有的数都转换为分数,然后调用之前编写类中的分数的加减乘除方法,然后完成求值,正在编写中。
(二)遇到的困难及解决方法【持续更新中......】
1.关于题目转换成后缀表达式的解决思路
题目转换成后缀表达式的原理是,如图:
这个要求的难点在于拿扫描到的操作符与栈顶的操作符比较优先级,高则进栈,低则输出栈顶元素并将扫描到的操作符压进栈里。
解决思路:
a.老师给的思路是编写一个数组,里面存放着操作符的优先级比较,然后在调用的时候用于比较。
b.对于老师给的思路,有一些不是很懂的地方。首先是存放操作符优先级比较的二维数组不太会编,然后就是具体调用时的代码实现不是很清楚。所以我转换了一下思路,从原理的本质上思考了一下:题目要求的四则运算只要求加减乘除四个操作符(因为我们组不用实现括号的产生),只有四个操作符的比较,通过if语句多判断几次就OK了。首先判断拿到的操作符是不是乘除一级的,如果是,则判断栈顶的操作符是不是加减,是则外面的优先级高,否则外面优先级低;如果拿到的操作符是加减一级的,则优先级肯定低于栈顶元素优先级。从而达到了判断优先级的目的。
(三)全部代码
第一部分:生成题目 //负责人:侯泽洋
import java.util.Stack;
import java.util.Random;
import java.util.ArrayList;
import java.util.Scanner;
class Questions {
ArrayList<Object> array = new ArrayList<Object>();
Random generator = new Random();
char[] newchar = {'+', '-', '*', '/'};
protected int number;
int NUM;
public Questions() {
number = 0;
}
public Object getQuestion(int num) {
int num1 = num;
while (num > 0) {
int figure = (int) generator.nextInt(9) + 1;
array.add(figure);
number = (int) (Math.random() * 4);
array.add(newchar[number]);
num--;
}
String obj = "";
while (num < 2 * num1) {
obj += array.get(num);
num++;
}
int other = (int) generator.nextInt(9) + 1;
array.add(other);
obj += other + "=";
return obj;
}
}
第二部分:题目运算 //负责人:周亚杰,侯泽洋
//生成后缀表达式
public class Calculations {
public static void main(String[] args) {
Questions questions=new Questions();
Stack stack = new Stack();
Scanner Scan=new Scanner(System.in);
char c;
int count=0,answer;
char[] operation = new char[100];
String str = (String) questions.getQuestion(3);
System.out.println("请回答以下问题:\n"+str);
System.out.println("请输入你的答案:");
answer=Scan.nextInt();
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (c >= '0' && c <= '9') {
operation[i] = c;
count++;
}
else {
if (c == '*' || c == '/') {
if (stack.empty()) {
stack.push((char) c);
} else if ((char) stack.peek() == '*' || (char) stack.peek() == '/') {
operation[i] = (char) stack.pop();
stack.push(c);
} else
stack.push(c);
} else if (c == '+' || c == '-') {
if (stack.empty()) {
stack.push(c);
} else if ((char) stack.peek() == '+' || (char) stack.peek() == '-') {
operation[i] = (char) stack.pop();
stack.push(c);
} else {
operation[i] = (char) stack.pop();
stack.push(c);
}
} else
stack.push(c);
}
}
int num = stack.size();
for (int a = 0; a < num; a++) {
operation[str.length() + a] = (char) stack.pop();
}
//后缀表达式计算 //负责人:周亚杰
Stack<Integer> stack1 = new Stack<Integer>();
int m, n, sum,num1=str.length()+(str.length()-count);
for (int b = 0; b <= num1; b++) {
if (operation[b] >= '0' && operation[b] <= '9')
stack1.push((int) operation[b]-48);
else {
if (operation[b] == '+') {
m = stack1.pop();
n = stack1.pop();
sum = n + m;
stack1.push(sum);
} else if (operation[b] == '-') {
m = stack1.pop();
n = stack1.pop();
sum = n- m;
stack1.push(sum);
} else if (operation[b] == '*') {
m = stack1.pop();
n = stack1.pop();
sum = n * m;
stack1.push(sum);
} else if (operation[b] == '/') {
m = stack1.pop();
n = stack1.pop();
sum = n / m;
stack1.push(sum);
}
else if (operation[b] == ' ')
continue;
}
}
if ((int)stack1.peek()==answer)
System.out.println("恭喜你答对了!");
else
System.out.println("很遗憾,答错了!答案是:"+stack1.peek());
}
}
三.个人贡献度划分
周亚杰:50%
侯泽洋:50%