结对编程--------四则运算 实验总结2

结对编程----------四则运算 实验总结2

结对对象

  • 20172301 郭恺
  • 20172328 李馨雨

过程截图

  • 这个是我们编写的main,叫ArithmeticTest1主要用于生成随机等级的题目,还有判题的结构也在这里。

package test1;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Scanner;
public class ArithmeticTest1 {
public static void main(String []args) {
Convert bee=new Convert();
int a;//用户输入的等级数。
int b;//用户想要做的题目数量。
int c;//用户算出所给题目的答案。
int d;//用户作对的题目数。
int e=0;
double f=0;
double h=0;
double i;
int ant=1;
String another;
String ban;
String luna;
String ann;
double abc;
Arithmetic num = new Arithmetic();
Comparision ben=new Comparision();
DecimalFormat fmt=new DecimalFormat("0.00");
NumberFormat fmt1= NumberFormat.getPercentInstance();
paring abb=new paring();
Scanner scan = new Scanner(System.in);
do{
System.out.println("Please enter the number of your test class(ep:1,2,3,4,5)😊;
a = scan.nextInt();
System.out.println("How many questions do you want: ");
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());
                        ban= bee.transit(ann);

                       if (ben.calculator(ban).equals(String.valueOf(c)))
                       {System.out.println("恭喜答对");
                       e++;}
                       else
                           System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(ban));

// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
}
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++;
ban= bee.transit(num.toString());
if(ben.calculator(ban).equals(String.valueOf(c)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(ban));
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
}
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++;
ban= bee.transit(num.toString());
if (ben.calculator(ban).equals(String.valueOf(c)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(ban));
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
}
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));
c = scan.nextInt();
ant++;
ban= bee.transit(num.toString());
if (ben.calculator(ban).equals(String.valueOf(c)))
{System.out.println("恭喜答对");
e++;}
else
System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(ban));
// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
}
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 5:
                    for (int x = 0; x < b; x++) {
                        num.level5();
                        System.out.print(num.toString(ant));
                        c = scan.nextInt();
                        ant++;
                        ban= bee.transit(num.toString());

                        if (ben.calculator(ban).equals(String.valueOf(c)))
                        {System.out.println("恭喜答对");
                            e++;}
                        else
                            System.out.println("很遗憾,答错了"+"正确答案是"+ben.calculator(ban));

// if()如果正确,输出恭喜答对,d++。否则输出正确答案。
}
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("please cheak your input.The result is out of expection.");
}
System.out.println("continue test or not (y/n)?");
another = scan.nextLine();
another = scan.nextLine();
}
while (another.equalsIgnoreCase("y"));
System.out.println();
}
}

  • 这是我们定义随机生成题目的方法的类叫Arithmetic,还定义了toString方法。

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 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
}

  • 这个我们做的是计算的方法。

package 结对编程;
import java.util.Stack;
import java.util.StringTokenizer;
// 后缀表达式求值
public class Comparision {
Stack stack = new Stack();
RationalNumber num1,num2,num3;
public Comparision() {
stack = new Stack();
}
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();
}
}

  • 这个是我们做的中缀表达式转后缀表达式的类(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 expre; // expression 表达式
Stack op; // 操作符
String result = "";
public Convert() {
expre = new ArrayList();
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;
}
}

  • 这是我们做的生成括号的类。

  • 这是引用的前面的例子,用于生成分数。

关键代码解释

  • 这是我们定义的生成随机题目的方法,我们采用了循环加随机数的方式。将四个运算符以char类型存在数组中,在方法内定义了随机数,通过随机产生数组的索引来实现随机调用运算符的目的。
    而数字直接使用了随机数类进行生成。==我们一共生成了4个等级的题目,一级只有加减,二级只有乘除,三级生成带括号的加减乘除的题目,四级生成带分数的题目。

  • RationalNumber类没什么好说的,只不过在这个方法中加入了一个取余的if判断,用于去除假分数。分子对分母取余为零的时候才会输出分数。我们使用了随机数类用于生成分子和分母。

  • 这是我们做的toString的方法,这个有一些特殊。我们设置了一个形参。将用户输入的题目数传进来,配合循环生成问题的题目数。
    中缀表达式转后缀表达式,后缀表达式的计算
    在我看来,这两个部分应该是四则运算的核心。为什么这么说呢?因为要想知道你的答案是否正确,必须要给出相对应的答案。
    • 把中缀表达式转换为后缀表达式。 其实是为了计算机更好的计算。如果按照正常的运算顺序,计算机无法判断1+2*3优先计算哪个。所以,我们必须人为地进行优先级排序,把1+2*3转换为123*+这样计算机就懂了原来先做乘法哦。
    • 实现中缀转后缀的方法的大致的思路是这样。我们要定义一个字符串和一个栈。因为我们最后输出的东西——后缀表达式,是一个字符串。根据刚刚的例子123*+。我们应该能够发现,当我们判断一个中缀表达式的时候,应该把数字直接划入字符串,符号入栈,然后再弹出。
          然后通过StringTokenizer类把字符串进行分割。
          之后,要比较栈里面符号优先级的顺序。把后入栈的符号和栈内的符号进行比较。如果后入的优先级高,那么就入栈;反之,则弹出栈内的符号后入栈。
    • 最后,后缀表达式如何计算出结果呢?
          首先,我都把数字转化为Rationalnumber类型。整数就是分母为1的分数。
          然后,通过switch语句,来分别调用Rationalnumber类的+-*/方法。

具体代码请参见前面两个类的代码。

  • 判题


这是我做的,主要将题目传到Convert,Comparision中进行运算,然后用if从句将用户输入的答案和计算结果进行比较。

遇到的困难及解决方法

  • 问题1:我们在生成的题目前加了题号,但是再生成是发现题号都是9。

  • 问题1解决方案:后来我们做了一个循环。如下图。

  • 问题2:双等号错误,在生成算式的时候带有两个等号。

  • 问题二解决方案:因为双等号一开始放在了循环里,所以会有错误,所以后来,我们将等号加在了结果里。

自己负责的项目

其实我们的小组没有很明确的分工,很多项目大家都参与了解决。我主要负责的地方是判题和加括号的地方。

小组贡献度

姓名 郭恺 段志轩 李馨雨
学号 20172301 20172304 20172328
贡献率(%) 38% 32% 30%
##对小组成员进行评价 - 20172301 郭恺 [博客链接](http://www.cnblogs.com/gk0625/p/9011430.html) 郭恺同志虽然有些放荡不羁,但是还是很有才的,我们组栈的内容主要是他负责的。 - 20172328 李馨雨 [博客链接](http://www.cnblogs.com/LXY462283007/p/9011036.html) 李馨雨同学很有耐心,而且很勤劳,而且和楼上的配合很好。 ##[码云项目链接](https://gitee.com/CS-IMIS-23/pair_programming.git) ##小组结对照片 ![](https://images2018.cnblogs.com/blog/1333068/201805/1333068-20180508221833427-1877382669.png) ## 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 |20 | | Test | 测试(自我测试,修改代码,提交修改) | 300 | 300 | |Size Measurement | 计算工作量(实际时间 | 2 | 2 | |Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 10 | | | 合计 | 4395 | 5229 |
posted @ 2018-05-08 22:27  段志轩  阅读(244)  评论(1编辑  收藏  举报