结对项目

这个作业属于哪个课程 计科22级12班
这个作业要求在哪里 结对项目
这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序
成员 梁晓君(3222004682) 阿丽娅·阿力木(3222004678)
github地址 作业github链接

PSP表格

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

效能分析


设计实现过程

  • 思路
    1.将整数统一为分数形式,利用random随机生成数和符号,以字符串数组的方式存储(一个数组只包含一个分数或者一个符号),编写加减乘除算法。
    2.在 题目 文件的控制台输入 题目数 数的上限 ,就可生成对应题目在 Execise.txt,对应答案存放在 Answer.txt 文件中,学生在 MyAnswer.txt中输入每题答案,对错和分数在 Grade.txt中呈现。
  • 流程图

代码说明

GenerateUtil.java

点击查看代码
public class GenerateUtil {

	/**
	 * 生成题目
	 * @param n 控制生成题目的个数
	 * @param r 控制题目中数值(自然数、真分数和真分数分母)的范围
	 */
	 public static void getExercise(int n,int r){

	        if (n < 1){
	            System.out.println("题目数量输入错误!(1<=n<=10000)");
	            return;
	        }
	        // 算式的结果
	        int sum = 0;
	        // 已生成题目的数量
	        int count = 0;
	        // a~h是数值,operator1~3是运算符,num代表运算符个数
	        int a,b,c,d,e,f,g,h,operator1,operator2,operator3,num;
	        // 存储题目以及答案(为方便,编号为1~n)
	        String[] exercise = new String[n + 1];
	        String[] results = new String[n + 1];
	        // 随机运算符:+ - * /,
	        // 0表示+, 1表示-, 2表示*, 3表示/
	        while (count<n){
	            operator1 = (int) (Math.random()*4);
	            operator2 = (int) (Math.random()*4);
	            operator3 = (int) (Math.random()*4);
	            a = (int) (Math.random() * r);
	            b = (int) (Math.random() * r);
	            c = (int) (Math.random() * r);
	            d = (int) (Math.random() * r);
	            e = (int) (Math.random() * r);
	            f = (int) (Math.random() * r);
	            g = (int) (Math.random() * r);
	            h = (int) (Math.random() * r);
	            num = (int) (Math.random() * 3);
	            // 一个运算符的情况下
	            if (b != 0 && d!= 0&& num == 0){
	                if (operator1 == 0){
	                    exercise[++count] = a + "/" + b + " + " + c + "/" + d + " =";
	                    // 存储临时值,方便化简
	                    sum = a * d + b * c;
	                    b = b * d;
	                    // 判断是否为假分数,下同
	                    if (sum > b){
	                        // 将其转换成带分数,下同
	                        results[count] = FractionUtil.changeToProperFraction(sum,b);
	                    }else {
	                        // 将分数化简,下同
	                        results[count] = FractionUtil.simplifiedFraction(sum,b);
	                    }
	                } else if (operator1 == 1) {
	                    if ((a/b) > (c/d)){
	                        exercise[++count] = a + "/" + b + " - " + c + "/" + d + " =";
	                        // 储存临时值,方便化简
	                        sum = a * d - b * c;
	                        b *= d;
	                        if (sum > b){
	                            results[count] = FractionUtil.changeToProperFraction(sum,b);
	                        }else {
	                            results[count] = FractionUtil.simplifiedFraction(sum,b);
	                        }
	                    }
	                } else if (operator1 == 2) {
	                    exercise[++count] = a + "/" + b + " * " + c + "/" + d + " =";
	                    // 储存临时值,方便化简
	                    sum = a * c;
	                    b *= d;
	                    if (sum > b){
	                        results[count] = FractionUtil.changeToProperFraction(sum,b);
	                    } else {
	                        results[count] = FractionUtil.simplifiedFraction(sum,b);
	                    }
	                } else if (operator1 == 3) {
	                    // 防止分母为0
	                    if (c == 0){
	                        continue;
	                    }
	                    exercise[++count] = a + "/" + b + " ÷ " + c + "/" + d + " =";
	                    sum = a * d;
	                    b *= c;
	                    if (sum > b){
	                        results[count] = FractionUtil.changeToProperFraction(sum,b);
	                    } else {
	                        results[count] = FractionUtil.simplifiedFraction(sum,b);
	                    }
	                }
	                // 有两个运算符的情况下
	            } else if (b != 0&& d != 0 && f != 0 && num ==1) {
	                if (operator1 == 0) {
	                    if (operator2 == 0){
	                        exercise[++count] = a + "/" + b + " + " + c + "/" + d + " + " + e + "/" + f + " =";
	                        sum = a*d*f + c*b*f + e*b*d;
	                        b = b * d * f;
	                        if (sum > b){
	                            results[count] = FractionUtil.changeToProperFraction(sum,b);
	                        }else {
	                            results[count] = FractionUtil.simplifiedFraction(sum,b);
	                        }
	                    } else if (operator2 == 1) {
	                        // 保证不会生成结果为负数的题目
	                        if (a/b + c/d - e/f > 0){
	                            exercise[++count] = a + "/" + b + " + " + c + "/" + d + " - " + e + "/" + f + " =";
	                            sum = a*d*f + c*b*f + e*b*d;
	                            b = b * d * f;
	                            if (sum > b){
	                                results[count] = FractionUtil.changeToProperFraction(sum,b);
	                            }else {
	                                results[count] = FractionUtil.simplifiedFraction(sum,b);
	                            }
	                        }
	                    } else if (operator2 == 2) {
	                        exercise[++count] = a + "/" + b + " + " + c + "/" + d + " * " + e + "/" + f + " =";
	                        sum = b*c*e + a*d*f;
	                        b = b * d * f;
	                        if (sum > b){
	                            results[count] = FractionUtil.changeToProperFraction(sum,b);
	                        }else {
	                            results[count] = FractionUtil.simplifiedFraction(sum,b);
	                        }
	                    } else if (operator3 == 3 && e != 0) {
	                        exercise[++count] = a + "/" + b + " + " + c + "/" + d + " + " + e + " ÷ " + f + " =";
	                        sum = a*d*e + b*c*f;
	                        b = b * d * e;
	                        if (sum > b){
	                            results[count] = FractionUtil.changeToProperFraction(sum,b);
	                        }else {
	                            results[count] = FractionUtil.simplifiedFraction(sum,b);
	                        }
	                    }
	                }
	            }
	        }

	        // 将生成的题目和答案存入txt文本文件
	        FileUtil.insertExercise(exercise);
	        FileUtil.insertAnswer(results);
	        // 将答案存起来
	        CorrectUtil.setResults(results);

	    }

}

这是生成题目的工具类,用随机函数设置随机符号和符号数。

FractionUtil.java

点击查看代码
public class FractionUtil {

    /**
     * 真分数化简
     * @param a 分子
     * @param b 分母
     * @return 化简后的分数(字符串形式)
     */
    public static String simplifiedFraction(int a, int b){
        // 分子为0,直接返回0
        if (a == 0){
            return 0+"";
        }
        // 当分母为1时,直接返回分子
        if (b==1){
            return a+"";
        }
        int simplified = simplified(a,b);
        return a/simplified + "/" + b/simplified;
    }

    /**
     * 处理假分数化简:化为真分数
     * @param a 分子
     * @param b 分母
     * @return 化简后的分数
     */
    public static String changeToProperFraction(int a,int b){
        // 当分子为0,直接返回0
        if (a == 0){
            return 0 + "";
        }
        if (b == 1){
            return a + "";
        }
        int temp = a / b;
        int t = a % b;
        if (t ==0 ){
            return temp + "";
        }
        int simplified = simplified(t,b);
        return temp+"'"+t/simplified+"/"+b/simplified;
    }

    /**
     * 递归调用,求最大公约数
     * @param a 分子
     * @param b 分母
     * @return 分子a与分母b的最大公约数
     */
    private static int simplified(int a,int b){
        if (b==0){
            return a;
        }else {
            return simplified(b,a%b);
        }
    }
}

这是处理分数的工具类,把真分数化简以及假分数转化真分数。

FileUtil.java

点击查看代码
public class FileUtil {
	File file = new File("1.txt");
    // 生成题目的文件路径
    private static final String exerciseFile = "Exercise.txt";
    // 答案的文件路径
    private static final String answerFile = "Answer.txt";

    /**
     * 生成题目文件
     * @param exercise 题目的数组
     */
    public static void insertExercise(String[] exercise) {
        File file = new File(exerciseFile);
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try{
            if (!file.exists()){
                file.createNewFile();
            }
            fos = new FileOutputStream(file);
            osw = new OutputStreamWriter(fos);
            bw = new BufferedWriter(osw);
            for (int i = 1; i < exercise.length; i++) {
                bw.write(i+"."+exercise[i]+"\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
          if (bw != null){
              try {
                  bw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          if (osw != null){
              try {
                  osw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          if (fos != null){
              try {
                  fos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
        }

    }
    
    /**
     * 生成答案文件
     * @param answer 答案的数组
     */
    public static void insertAnswer(String[] answer){
        File file = new File(answerFile);
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try{
            if (!file.exists()){
                file.createNewFile();
            }
            fos = new FileOutputStream(file);
            osw = new OutputStreamWriter(fos);
            bw = new BufferedWriter(osw);
            for (int i = 1; i < answer.length ; i++) {
                bw.write(i+"."+" "+answer[i]+"\n");
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (osw!=null){
                try {
                    osw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

}
这是把题目和答案存入文件的工具类。

测试运行

生成十个题目



项目小结

  • 项目成败得失
    在项目初期,我们对需求的理解不够透彻,导致在开发过程中出现了一些不必要的返工,大大增加了我们开发项目的时间。
  • 分享经验
    我觉得结对项目中沟通和配合还是很重要的,我和队员本来就是好朋友在一个宿舍,在项目开发中出现任何问题我们都能及时沟通解决。 * 结对感受:结对开发的时候两个人一起配合讨论能更好的分析项目需求,两人配合可以避免一些不必要的错误。
  • 对彼此的评价
    阿丽娅:此次项目代码大体是她来负责,我平时思考反应会慢一点,她会很耐心的帮助我。
    梁晓君:我的队员观察能力很强,会很细心的发现一些我没发现的问题。
posted @ 2024-09-28 19:35  LLLLJun  阅读(19)  评论(0编辑  收藏  举报