20172328的结对编程四则运算第二周-整体总结
20172328结对编程四则运算第二周-整体总结
设计思路
- 1.以Arithmetic为主类,在其中编写有关的四个等级题目方法最后在这周实现了有括号的方法并加在了等级三题目中。
- 2.Convert类是中缀转后缀的类,Comparision是后缀表达式计算的类。通过在方法头中传参实现计算全过程。
- 3.ArithmeticTest是面向用户类,通过用户的选择和做题,程序随机按照用户所选产生的各级题目以及比对给出用户结果,最后计算出用户的正确率。
- 4.Arithmetic类中主要运用循环和Random类来产生随机数和随机符号,Convert类中主要通过栈和数组的共同应用来解决中缀表达式变后缀表达式。Comparsion类中也是用栈来进行计算从而得到后缀表达式结果。ArithmeticTest类是最能体现程序应用的一个面向用户类,里面创建了各个类的对象,用Scanner类与用户交互,用Convert类和Comparsion类帮用户判题,用DecimalFormat;NumberFormat类来格式化用户答对题的百分数。用Swithch-case语句来找到各个级别的题目。
扩展需求
- 1.这周我们小组开始研究如何将题目写入文件并从文件中读题判题,然后再写入文件的这个拓展需求。暂时还没有写出来。可能在新的一周内会研究去重问题。
遇到的困难和解决办法
- 1.当输入答案正确的时候直接跳出,不正确答案没有提示也没有继续。
-
问题1解决方案:在Arithmetic类里面重载了一个toStrng方法,因为在面向用户类里面使用的方法需要的参数不一样。所以需要再加上一个toString方法。
-
2.当我们把正确率加上后,我们的程序在运行时遇到分数出现了错误。
-
问题2解决方案:我们的分数最终转换出来是字符串型的,所以在前面应该定义一个字符串型变量c1来储存,然后再去与后缀计算结果比对。
-
3.当我在改正问题二时只改正了
c1 = scan.next();
而没有改正if (ben.calculator(lastexpression).equals(String.valueOf(c1)))
所以出现了我的用户哭死在我面前系列!
- 问题3解决方案:我初始化的c是0,所以当我没有去改正后面语句中的c1时,出现了用户即使作对了题目也判断出错的问题,因为程序一直将用户输入的字符串与数值0比较,肯定就不相同了。最后改正成功。
三人贡献度表格
姓名 | 郭恺 | 段志轩 | 李馨雨 |
---|---|---|---|
学号 | 20172301 | 20172304 | 20172328 |
贡献率(%) | 38% | 32% | 30% |
关键代码
- Arithmetic类(生成题目类)
package 结对编程;
import java.util.ArrayList;
import java.util.Random;
public class Arithmetic {
char[] operator = {'+', '-', '*', '÷'};
Random generator = new Random();
int num1, num2, num3,num4, a;
private String result="";
ArrayList<String> questionName = new ArrayList<>();
// 输出1级题目:+、-
public String level1() {
num1 = generator.nextInt(20)+1;
num2 = generator.nextInt(20)+1;
num3 = generator.nextInt(2);
a = generator.nextInt(1);
result = num1 + " " + operator[num3] + " " + num2;
for (int x = 0; x <= a; x++) {
num2 = generator.nextInt(20)+1;
num3 = generator.nextInt(2);
result += " " + operator[num3] + " " + num2;
}
return result;
}
// 输出2级题目:*、÷
public String level2() {
num1 = generator.nextInt(20)+1;
num2 = generator.nextInt(20)+1;
num3 = generator.nextInt(2) + 2;
a = generator.nextInt(3);
result = num1 + " " + operator[num3] + " " + num2;
for (int x = 0; x <= a; x++) {
num2 = generator.nextInt(20)+1;
num3 = generator.nextInt(2) + 2;
result += " " + operator[num3] + " " + num2;
}
return result;
}
// 输出3级题目:+、-、*、÷
public String level3() {
num1 = generator.nextInt(20)+1;
num2 = generator.nextInt(20)+1;
num3 = generator.nextInt(4);
result =""+ num1 + " "+ operator[num3] + " " + num2;
a = generator.nextInt(3);
for (int x = 0; x <= a; x++) {
num3 = generator.nextInt(4);
num4 = generator.nextInt(2);
num2 = generator.nextInt(20)+1;
if(a!=0)
{
result += " " + operator[generator.nextInt(2)] ;
}
a--;
result += " "+Arithmetic.bracket() + " " + operator[num3]+ " " + num2 ;
}
return result;
}
//生成分数.
public RationalNumber fraction() {
int numer = generator.nextInt(20)+1;
int denom = generator.nextInt(20)+1;
RationalNumber a = new RationalNumber(numer, denom);
if (numer > denom)
if (numer % denom == 0)
return a;
else
a = a.reciprocal();
else
return a;
return a;
}
//四级题目
public String level4() {
Arithmetic[] fraction = new Arithmetic[5];
RationalNumber[] fraction1 = new RationalNumber[5];
for (int x = 0; x < fraction.length; x++) {
Arithmetic a = new Arithmetic();
fraction1[x] = a.fraction();
}
num3 = generator.nextInt(4);
a = generator.nextInt(2);
result = fraction1[0] + " " + operator[num3] + " " + fraction1[1];
if (a > 2)
for (int x = 2; x < a; x++) {
num3 = generator.nextInt(4);
result += " " + operator[num3] + " " + fraction1[x];
}
return result;
}
// 重写toString方法
public String toString(int number) {
String result1="";
result1= "问题" + number + ": " + result + " = ";
return result1;
}
public String toString(){
String result = "";
result = this.result;
return result;
}
//生成括号的方法。
public static String bracket()
{
char[] operator = {'+', '-', '*', '÷'};
Random generator = new Random();
int num1, num2, num3, num4,a;
String result1;
String ab;
String []abc=new String [2];
num1 = generator.nextInt(20) + 1;
num2 = generator.nextInt(20) + 1;
num3 = generator.nextInt(4);
num4 = generator.nextInt(2);
ab = " "+ operator[num3]+" ( "+ (generator.nextInt(20)+1) +" "+ operator[num4]+ " "+(generator.nextInt(20)+1)+" ) ";
abc[1]=ab;
abc[0]=" ";
result1 = num1 +abc[generator.nextInt(2)] + operator[num3]+" "+num2;
return result1;
}
// public void
}
- Convert类(中缀转后缀类)
package 结对编程;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
public class Convert {
List<String> expre; // expression 表达式
Stack<String> op; // 操作符
String result = "";
public Convert() {
expre = new ArrayList<String>();
op = new Stack();
}
// 中缀表达式转后缀表达式的转换方法。
public String transit(String q) // question
{
String a; // a 是字符
StringTokenizer tokenizer = new StringTokenizer(q);
while (tokenizer.hasMoreTokens()) {
a = tokenizer.nextToken();
if (a.equals("("))
op.push(a); // 如果是"(",入栈
else if (a.equals("+") || a.equals("-")) {
if (!op.isEmpty()) {
if (op.peek().equals("("))
op.push(a); // 如果栈顶"(",运算符入栈
else {
expre.add(op.pop()); // 先移除栈顶元素到列表中,再将运算符入栈
op.push(a);
}
} else {
op.push(a); // 栈为空,运算符入栈
}
} else if (a.equals("*") || a.equals("÷")) {
if (!op.isEmpty()) {
if (op.peek().equals("*") || op.peek().equals("÷")) {
expre.add(op.pop());
op.push(a);
} else
op.push(a);
} else
op.push(a); // 如果栈为空,运算符入栈
} else if (a.equals(")")) {
while (true) {
String b = op.pop();
if (!b.equals("(")) {
expre.add(b);
} else {
break;
}
}
} else {
expre.add(a); // 如果为操作数,入列表
}
}
while (!expre.isEmpty() && !op.isEmpty()) {
expre.add(op.pop());
}
for (String x : expre)
result += x + " ";
return result;
}
}
- Comparsion类(计算后缀表达式类)
package 结对编程;
import java.util.Stack;
import java.util.StringTokenizer;
// 后缀表达式求值
public class Comparision {
Stack<String> stack = new Stack<String>();
RationalNumber num1,num2,num3;
public Comparision() {
stack = new Stack<String>();
}
public String calculator(String q)
{
String op1, op2, result;
String a;
StringTokenizer tokenizer = new StringTokenizer(q);
while (tokenizer.hasMoreTokens())
{
a = tokenizer.nextToken();
if(a.equals("+") || a.equals("-") || a.equals("*") || a.equals("÷"))
{
// 把栈顶的操作数弹出,转换为RationalNumber类型
op2 = stack.pop();
num2 = conToRantionalNum(op2);
// 继续把栈顶的操作数弹出,转换为RationalNumber类型
op1 = stack.pop();
num1 = conToRantionalNum(op1);
//计算结果
result = calculate(num1,a.charAt(0),num2);
stack.push(result.toString());
}
else
stack.push(a);
}
result = stack.pop();
return result;
}
public RationalNumber conToRantionalNum (String a)
{
String numer,denom; // numer分子,denom分母
// 把分数a/b以"/"为标记分割开
StringTokenizer tokenizer1 = new StringTokenizer(a,"/");
numer = tokenizer1.nextToken();
if (tokenizer1.hasMoreTokens())
// 如果分母不为1
{
denom = tokenizer1.nextToken();
num1 = new RationalNumber(Integer.parseInt(numer), Integer.parseInt(denom));
}
else
// 如果分母为1
{
num1 = new RationalNumber(Integer.parseInt(numer), 1);
}
return num1;
}
// 计算+、-、*、÷
public String calculate(RationalNumber op1, char operation, RationalNumber op2)
{
RationalNumber result = new RationalNumber(0,1);
switch (operation)
{
case '+':
result = op1.add(op2);
break;
case '-':
result = op1.subtract(op2);
break;
case '*':
result = op1.multiply(op2);
break;
case '÷':
result = op1.divide(op2);
break;
}
return result.toString();
}
}
- ArithmeticTest类(面向用户类)
package 结对编程;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Scanner;
public class ArithmeticTest1 {
public static void main(String []args) {
Convert bee=new Convert();
Arithmetic num = new Arithmetic();
Comparision ben=new Comparision();
DecimalFormat fmt=new DecimalFormat("0.00");
NumberFormat fmt1= NumberFormat.getPercentInstance();
int a;//用户输入的等级数。
int b;//用户想要做的题目数量。
int c = 0;//用户算出所给题目的答案。
String c1;//专门为level4设置的字符串类型的输入。
int d;//用户作对的题目数。
int e=0;//用户答对的题目数.
int ant=1;//题目编号数字.
double f=0;//求出来正确率的小数数形式。
double h;//一共做的题目数量变成double型。
double i;//用户做对的题目数量变成double型。
String another;////让用户输出y/n的Scanner类型。
String lastexpression;//后缀表达式字符串型。;
String luna;//转化成的正确率百分数模式。
String ann;
double abc;//将字符串小数点型正确率变成double型数字。
// paring abb=new paring();
Scanner scan = new Scanner(System.in);
System.out.println("欢迎使用四则运算题库!");
do{
System.out.println("请选择题目难度等级(例如:1,2,3,4):");
a = scan.nextInt();
System.out.println("请选择题目数量:");
b = scan.nextInt();
e=0;
ant=1;
switch (a) {
case 1:
for (int x = 0; x < b; x++) {
num.level1();
System.out.print(num.toString(ant));
c = scan.nextInt();
ant++;
// ann=abb.mmm(num.toString());
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
lastexpression= bee.transit(num.toString());
if (ben.calculator(lastexpression).equals(String.valueOf(c)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(lastexpression));
}
h=(double)b;
i=(double)e;
f=i/h;
luna= fmt.format(f);
abc= Double.valueOf(luna);//把一个字符串表示的数字变成真正的数字.
System.out.println("正确率是"+fmt1.format(abc));
System.out.println();//给题目换行
break;
case 2:
for (int x = 0; x < b; x++) {
num.level2();
System.out.print(num.toString(ant));
c = scan.nextInt();
ant++;
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
lastexpression= bee.transit(num.toString());
if(ben.calculator(lastexpression).equals(String.valueOf(c)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(lastexpression));
}
h=(double)b;
i=(double)e;
f=i/h;
luna= fmt.format(f);
abc= Double.valueOf(luna);
System.out.println("正确率是"+fmt1.format(abc));
System.out.println();//给题目换行
break;
case 3:
for (int x = 0; x < b; x++) {
num.level3();
System.out.print(num.toString(ant));
c = scan.nextInt();
ant++;
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
lastexpression= bee.transit(num.toString());
if (ben.calculator(lastexpression).equals(String.valueOf(c)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(lastexpression));
}
h=(double)b;
i=(double)e;
f=i/h;
luna= fmt.format(f);
abc= Double.valueOf(luna);
System.out.println("正确率是"+fmt1.format(abc));
System.out.println();//给题目换行
break;
case 4:
for (int x = 0; x < b; x++) {
num.level4();
System.out.print(num.toString(ant));
c1 = scan.next();
ant++;
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
lastexpression= bee.transit(num.toString());
if (ben.calculator(lastexpression).equals(String.valueOf(c1)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(lastexpression));
}
h=(double)b;
i=(double)e;
f=i/h;
luna= fmt.format(f);
abc= Double.valueOf(luna);
System.out.println("正确率是"+fmt1.format(abc));
System.out.println();//给题目换行
break;
default:
System.out.println("请检查您的输入.你输入的结果超出范围了.");
}
System.out.println("要继续做题吗?(y/n)?");
another = scan.next();
}
while (another.equalsIgnoreCase("y"));
System.out.println();
}
}
对结对小伙伴做出评价
结对编程小组照片
码云链接
PSP时间规划
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 65 |
Estimate | 估计这个任务需要多少时间 | 3 | 2 |
Development | 开发 | 2000 | 3000 |
Analysis | 需求分析 (包括学习新技术) | 350 | 300 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 10 |
Design UML | 设计项目UML类图 | 60 | 60 |
Coding | 具体编码 | 1500 | 2000 |
Code Review | 代码复审 | 30 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 300 | 300 |
Size Measurement | 计算工作量(实际时间 ) | 2 | 2 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 10 |
合计 | 4395 | 5229 |