结对项目

软件工程 网工1934-软件工程 (广东工业大学 - 计算机学院)
作业要求 实现一个自动生成小学四则运算题目的命令行程序
作业目标 1.使用 -n 参数控制生成题目的个数。
2.使用 -r 参数控制题目中数值的范围。
3.生成的题目中计算过程不能产生负数。
4.生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。
5.每道题目中出现的运算符个数不超过3个。
6.程序一次运行生成的题目不能重复。
7.在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。
8.程序应能支持一万道题目的生成。
9.程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。
队员:3119005390欧振浩

GitHub 链接

一、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
· Estimate · 估计这个任务需要多少时间 740 1110
Development 开发
· Analysis · 需求分析 (包括学习新技术) 240 360
· Design Spec · 生成设计文档 40 30
· Design Review · 设计复审 10 10
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 20
· Design · 具体设计 60 50
· Coding · 具体编码 180 240
· Code Review · 代码复审 60 100
· Test · 测试(自我测试,修改代码,提交修改) 60 120
Reporting 报告
· Test Report · 测试报告 30 40
· Size Measurement · 计算工作量 20 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 20 20
合计 740 1110

二、效能分析

三、设计实现过程

共使用了四个类

homework 类

是main方法所在的类,可调用其他类的静态方法实现需求

calculator 类

计算加减乘除以及返回答案的类

reductionofFraction 类

将输入的两个数进行约分的类

change 类

将假分数化为带分数的类

各类之间关系

四、代码说明

homework 类

import java.io.*;
import java.util.*;

public class homework {
    private static Random random = new Random();
    public static int range;
    public static void main(String[] args) {
        // 依次转化为字符串,设置题目
        System.out.println("请输入“ -r 数字”或“-r 数字 -n 数字”");
        if(args[0]!="-r") {
            System.out.println("请输入“ -r 数字”或“-r 数字 -n 数字”");
        }
        else {
            range = Integer.parseInt (args[1]);
        }
        int num;
        if(args[2]=="-n") {
            num = Integer.parseInt (args[3]);
        }
        else {
            num = 10000;
        }
        //int num=10,range=10;

        for(int j=0;j<num;j++) {
            int a[] = new int[6];
            for (int i = 0; i < 6; i++) {
                a[i] = random.nextInt(range);
            }//创建随机数
            int b[] = new int[2];//创建随机运算符
            b[0] = random.nextInt(4);
            b[1] = random.nextInt(5);//可能不存在第二个运算符
            b[1] = 4;//技术有限先不考虑第二个运算符

            int c[] = new int[6];//计算
            if (b[1] == 4) {
                c = calculator.main(a[1], a[2], a[3], a[4], b[0]);
            }

            if(c[5]!=-1) {//若答案的除数非0才会进入
                String exercises[] = new String[1];//构建题目
                exercises[0] = reductionofFraction.main(c[0], c[1]);
                switch (b[0]) {
                    case 0: {
                        exercises[0] += " + ";
                        break;
                    }
                    case 1: {
                        exercises[0] += " - ";
                        break;
                    }
                    case 2: {
                        exercises[0] += " × ";
                        break;
                    }
                    case 3: {
                        exercises[0] += " ÷ ";
                        break;
                    }
                }
                exercises[0] += reductionofFraction.main(c[2], c[3]);
                exercises[0] += " =";

                String answer[] = new String[1];//计算答案
                answer[0] = reductionofFraction.main(c[4], c[5]);


                FileWriter fExercises = null;
                try {
                    File f = new File("Exercises.txt");//题目写入
                    fExercises = new FileWriter(f, true);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (exercises[0] != null) {
                    PrintWriter pExercises = new PrintWriter(fExercises);
                    pExercises.println(j + 1 + "." + exercises[0]);
                    pExercises.flush();
                    try {
                        fExercises.flush();
                        pExercises.close();
                        fExercises.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                FileWriter fAnswer = null;
                try {
                    File f = new File("Answer.txt");//答案写入
                    fAnswer = new FileWriter(f, true);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (exercises != null) {
                    PrintWriter pAnswer = new PrintWriter(fAnswer);
                    pAnswer.println(j + 1 + "." + answer[0]);
                    pAnswer.flush();
                    try {
                        fAnswer.flush();
                        pAnswer.close();
                        fAnswer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            else j--;//否则此次随机过程作废
        }
        // 退出程序
        System.exit(0);
    }
}

calculator 类

public class calculator {
    public static int[] main(int a, int b,int c,int d,int x) {
        int numerator=0,denominator = 0;
        int answer[]=new int[6];
        if(b!=0&&d!=0) {//判定分母是否有0
        }
        else{//若有零则将分母置1
            b=1;d=1;
        }
        switch (x) {
            case 0: {//加
                numerator = a * d + b * c;
                denominator = b * d;
                break;
            }
            case 1: {//减
                if ((a * d - b * c) < 0) {//若出现负数则减数与被减数互换
                   int xx=a;
                   a=c;
                   c=xx;
                   xx=b;
                   b=d;
                   d=xx;
                }
                numerator = a * d - b * c;
                denominator = b * d;
                break;
            }
            case 2: {//乘
                numerator = a * c;
                denominator = b * d;
                break;
            }
            case 3: {//除
                numerator = a * d;
                denominator = b * c;//c有概率为0,导致报错
                break;
            }

        }
        answer[0]=a;
        answer[1]=b;
        answer[2]=c;
        answer[3]=d;
        answer[4]=numerator;
        if (denominator!=0) {//判定答案的除数是不是0,若是,则返回-1,此次报废
            answer[5] = denominator;
        }
        else{
            answer[5] = -1;
        }
        return answer;
    }
}

reductionofFraction 类

public class reductionofFraction {
    public static int gcd(int m,int n)//辗转相除法求最大公约数
    {   if(n == 0){
        return m;
    }
        int r = m%n;
        return gcd(n,r);
    }
    public static String main(int a, int b) {// 分数约分,用于计算结果
        int i = gcd(a,b);
        int x = a / i;// 分子
        int y = b / i;// 分母
        if (x == 0) {
            return "0";
        }
        //if(y==0) return "y=0";曾用于测试哪里使程序报错
        if(y==1) return x+"";
        else  return change.main(x,y);

    }
}

change 类

public class change {
    public static String main(int a, int b) {//判断假分数,并化假分数为带分数
        if(a>=b) {
            int c;
            c=a/b;
            int d;
            d=a%b;
            {
                if(d==0) {
                    return c+"";//若两数可以整除
                }
                return c+"'"+d+"/"+b;//分子大于分母可以转化为带分数
            }
        }return a+"/"+b;//分子小于分母不能转化为带分数
    }
}

五、测试运行

可以生成10道,当不指定题目数量时默认生成10000道

六、项目小结

起初想做出两个及以上运算符的四则运算,但是一旦引入括号后问题感觉复杂了很多,在网上查到了可以使用逆波兰式解决这个问题,但因为自己使用的计算答案的过程有将题目里的子表达式做改变,想了很久也没有想到如何在这个方法里插入逆波兰式。
而且时间匆忙,打分功能也还没来得及做。但是在查阅资料的过程中收获良多。

posted @ 2021-10-26 01:31  全麻  阅读(39)  评论(0编辑  收藏  举报