结对项目:自动生成小学四则运算题目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834/homework/11148
这个作业的目标 队友之间相互协作,实现一个自动生成小学四则运算题目的命令行程序

项目成员:

甄海晖 学号:3118005300
袁宇芳 学号:3118005297
###[toc]

1. Github仓库

https://github.com/YuanYF6/calculation

2. PSP表格

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

3.效能分析




4.设计实现过程


###5.代码说明
-5.1随机生成运算式。最多只有3个运算符。左括号和右括号数量都小于或等于运算符的数量,且左括号和右括号数量相等。每生成一个问题,就用Check.mainCheck方法检查运算式是否符合要求,若不符合,则剔除;若符合,则接着用Generate.generateAnswer检查答案是否为负数;若为负数,则剔除

public static void generateProblems(int problemCount,int numericalRange){       //生成问题
    //problemCount问题数量,numericalRange数值范围
 private static final String[] symbols = {"+","-","×","÷"};
    Random random = new Random();
    int e;
    String num;
    int count = 1,symbol = 0;
    int Parentheses;//总括号数
    int openParentheses,closeParentheses;   //左括号,右括号个数

    for(int i = 1;i<=problemCount;i++){
        boolean invalid = false;
        String expression = "";
        do{
            e = random.nextInt(4);      //随机生成运算符的个数,不超过3个。
        }while(e==0);
        Parentheses = openParentheses = random.nextInt(e);
        closeParentheses = 0;
        int[] ParenthesesRepeat = new int[Parentheses];
        int parindex = 0;
 //            System.out.println("Parentheses = "+Parentheses);
 //            System.out.println("e = "+e);
        for(int j = 0;j<=e;j++){
            boolean probability;
            if(j==e){
                if(symbol==3){  //若有÷号
                    do{
                        num = generateNum(numericalRange);
                    }while("0".equals(num));
                }
                else num = generateNum(numericalRange);
                expression=expression+" "+num+" ";
                if(closeParentheses!=0){
                    do{
                        expression+=") ";
                        closeParentheses--;
                    }while(closeParentheses!=0);
                }
                if(Check.mainCheck(expression,true)){//剔除不符合要求的问题;题目数-1;
                    i--;
                    break;
                }
      //                 System.out.println("已完成问题生成:"+count+"."+expression);
                if("ERROR".equals(generateAnswer(count,expression))){//检查答案是否为负数,若是则剔除这道题;
                    i--;
                    break;
                }
                IOModule.outPut(count,expression,true);
                count++;
                break;
            }
            if(symbol==3){
                do{
                    num = generateNum(numericalRange);
                }while("0".equals(num));
            }
            else num = generateNum(numericalRange);
            symbol = random.nextInt(4);
            if(openParentheses!=0){
                String exp = "";
                do{
                    if(parindex!=0 && ParenthesesRepeat[parindex-1]==(e-j))
                        break;
                    if(invalid && j==e-1)
                        break;
                    probability = (random.nextInt(e)>=Parentheses);
                    if(probability){
                        if(!invalid)
                            invalid = true;
                        exp=exp+" (";
                        openParentheses--;  closeParentheses++; ParenthesesRepeat[parindex]++;
                    }
                }while(probability&&openParentheses!=0);
                exp=exp+" "+num+" "+symbols[symbol];
 //                  System.out.println("左:");
 //                    System.out.println(expression);
                if(ParenthesesRepeat[parindex]!=0){
                    parindex++;
                    expression+=exp;
                    continue;
                }
            }
            if(closeParentheses!=0){
  //                    String exp = "";
                expression=expression+" "+num+" ";
                do{
                    probability = (random.nextInt(e)>=Parentheses);
  //                        System.out.println("j= "+j+"   e= "+e);
  //                      System.out.println("ParenthesesRepeat[parindex-1]= "+ParenthesesRepeat[parindex-1]);
                    if(ParenthesesRepeat[parindex-1]>=(e-j))
                        probability = true;
                    if(probability){
                        expression+=") ";
                        closeParentheses--;
                        ParenthesesRepeat[parindex-1]--;
                    }
                    if(ParenthesesRepeat[parindex-1]==0){
                        parindex--;
                    }else
                        break;
                }while(probability&&closeParentheses!=0);
                expression=expression+symbols[symbol];
//                    System.out.println("右:");
//                    System.out.println(expression);
                continue;
            }
            expression=expression+" "+num+" "+symbols[symbol];
        }
    }
}

-5.2计算答案,拆分表达式,先计算括号内,然后计算括号外。先乘除后加减

 public static String calculation(String[] expression){       //计算答案
      int count = 0;
      boolean haveBrackets = false;
      String[] exp = new String[expression.length];
      String[] e = new String[expression.length];
       for(int i = 0,j = 0,k = 0;i<expression.length;i++){      //将括号分割成式子
         if(expression[i]==null)
             break;
         if(("(").equals(expression[i])){
             count++;
             if(!haveBrackets){
                 haveBrackets = true;
                 continue;
             }
         }
         if((")").equals(expression[i])){
             count--;
             if(count==0){
                haveBrackets = false;
                String temp = calculation(e);
                if("ERROR".equals(temp))
                    return "ERROR";
                exp[k++] = temp;
                continue;
             }
         }
         if(!haveBrackets)
            exp[k++] = expression[i];
         else e[j++] = expression[i];        //要递归的式子
     }

 //                  System.out.println("exp=     ");
 //                   for(String s : exp){
 //                       System.out.print(s);
 //                   }
 //                   System.out.println("");

 //处理乘除加减法
    String result = "0";
    int lastSymbol = 1;
    String[] exp2 = new String[exp.length];
    String lastNum = null;
    for(int i = 0,k = 0;i<exp.length;i++){
        if(("×").equals(exp[i])||("÷").equals(exp[i])){     //一级处理,先计算乘除算术表达式
            String num = "1";
            if(lastNum!=null)
                num = lastNum;
            int firstSymbol = 0;
            for(;!(("+").equals(exp[i])||("-").equals(exp[i]));i++){
                if(firstSymbol==1){     //乘法
                    num = calculation.times(num,exp[i]);
                    firstSymbol=0;
                }else if(firstSymbol==2){   //除法
                    num = calculation.divides(num,exp[i]);
                    if("ERROR".equals(num))
                        return "ERROR";
                    firstSymbol=0;
                }else if(("×").equals(exp[i])){
                    firstSymbol=1;
                }else if(("÷").equals(exp[i])){
                    firstSymbol=2;
                }
                if(i==exp.length-1)
                    break;
            }
            exp2[k-1] = String.valueOf(num);
            if(i==exp.length-1)
                break;
        }
        lastNum = exp[i];
        exp2[k++] = lastNum;
    }
//       System.out.println("完成一级处理");

    for(String str : exp2){          //二级处理,计算加减算术表达式
        if(str==null)
            continue;
        switch (str){
            case "+":
                lastSymbol = 1;
                break;
            case "-":
                lastSymbol = 2;
                break;
            default:
//                  String num = str;
                switch (lastSymbol){
                    case 1:
                        result = calculation.plus(result,str);
                        break;
                    case 2:
                        result = calculation.minus(result,str);
                        break;
                }
        }
    }
 //        System.out.println(result);
 //        System.out.println("完成二级处理");

    return result;
}

###6.测试运行
程序能支持生成10000道题和程序计算出的答案

程序计算出的结果

将Answers.txt的答案复制到answerfile.txt,并将1-5题的答案改为随意的错误答案,将两份答案对比,将结果输出到Grade.txt中。


###7.项目小结
这次项目是由两位编程能力相差较大的同学共同编写的。由编程能力较强的同学先起总的项目所需要的类,然后再由我编写其中比较容易写出的方法。对于一些对于我来说难以实现的方法,我们一般先讨论,两人一起合作,能产生更多更好的想法。还能相互帮助解决问题。效率较高。我:对java的熟悉度不够,项目经验不多,对于这次大佬带我机会,我也是尽自己的能力多学了点东西。这次结对也充分锻炼了两个人的合作。虽然整个代码有些功能写的不是很好,但我们也总结了经验,努力提升自己。

posted @ 2020-10-12 23:47  YuanYF6  阅读(164)  评论(0编辑  收藏  举报