结对编程--中小学数学卷子自动生成程序代码互评

本篇博客根据软件工程项目创新课程设计的个人项目要求,对黄泽云同学的项目代码进行分析评价。


一、整体评价

  • 结构上,该项目代码由两个文件组成。分别是Paper.java和PaperCreate.java。其中,PaperCreate.java定义了用户类和功能性方法,Paper.java定义了主类。

  • 功能上,经过测试,可以满足个人项目中所有的需求。

  • 编码规范上,采用IDE中自带的编码格式,编码规范。


二、细节分析

项目实现的难点在于出题的随机性、合法性和无重复性。下面具体就产生题目的函数进行分析评价。

  • 该同学采用Random实现随机性。并且分两步完成一道题目的生成。首先是生成由操作数和操作符组合成的字符串。

    int i = 0;
    if (grade.equals("小学")) i = rand.nextInt(4) + 2;
    if (grade.equals("初中") || grade.equals("高中")) i = rand.nextInt(5) + 1;

    String[] q = new String[2 * i - 1];

    for (int j = 0; j < 2 * i - 1; j++) {
      q[j] = "";
    }
    int ss = 1;

    for (int j = 0; j < 2 * i - 1; j += 2) {
      if (grade.equals("小学")) q[j] = String.valueOf((rand.nextInt(100) + 1));

      if (grade.equals("初中")) {
        int s = rand.nextInt(3);
        if (s == 0) {
          q[j] = String.valueOf((rand.nextInt(100) + 1));
        } else if (s == 1) {
          q[j] = ("√" + (rand.nextInt(100) + 1));
          ss = 0;
        } else {
          q[j] = ((rand.nextInt(100) + 1) + "^2");
          ss = 0;
        }
      }

      if (grade.equals("高中")) {
        int s = rand.nextInt(6);
        if (s == 0) {
          q[j] = String.valueOf((rand.nextInt(100) + 1));
        } else if (s == 1) {
          q[j] = ("√" + (rand.nextInt(100) + 1));
        } else if (s == 2) {
          q[j] = ((rand.nextInt(100) + 1) + "^2");
        } else if (s == 3) {
          q[j] = ("sin" + (rand.nextInt(100) + 1));
          ss = 0;
        } else if (s == 4) {
          q[j] = ("cos" + (rand.nextInt(100) + 1));
          ss = 0;
        } else {
          q[j] = ("tan" + (rand.nextInt(100) + 1));
          ss = 0;
        }
      }

      if (j == 2 * i - 2) {
        if (ss == 1) {
          if (grade.equals("初中")) {
            q[j] = "√" + q[j];
          }
          if (grade.equals("高中")) {
            q[j] = "cos" + q[j];
          }
        }
        break;
      }
    }

    for (int j = 1; j < 2 * i - 1; j += 2) {
      int s = rand.nextInt(4);
      if (s == 0) {
        q[j] = "+";
      } else if (s == 1) {
        q[j] = "-";
      } else if (s == 2) {
        q[j] = "*";
      } else {
        q[j] = "/";
      }
    }
  • 第二步考虑括号的位置,采用枚举法,先枚举出所有可能的位置写进数组,再从中随机出合法的组合。

image存了所有可能的括号的位置

    for (int j = 1; j < 2 * i - 1; j += 2) {
      int s = rand.nextInt(4);
      if (s == 0) {
        q[j] = "+";
      } else if (s == 1) {
        q[j] = "-";
      } else if (s == 2) {
        q[j] = "*";
      } else {
        q[j] = "/";
      }
    }

    if (i == 1) {
      question = q[0];
    }
    if (i == 2) {
      question = q[0] + q[1] + q[2];
    }
    if (i == 3) {
      if (rand.nextInt(2) == 0) {
        int r = rand.nextInt(2);
        q[n[r][0]] = "(" + q[n[r][0]];
        q[n[r][1]] = q[n[r][1]] + ")";
      }
      question = q[0] + q[1] + q[2] + q[3] + q[4];
    }
    if (i == 4) {
      int brackets = rand.nextInt(3);
      if (brackets == 1) {
        int r1 = rand.nextInt(5);
        q[n[r1][0]] = "(" + q[n[r1][0]];
        q[n[r1][1]] = q[n[r1][1]] + ")";
      } else if (brackets == 2) {
        int r1 = rand.nextInt(5);
        q[n[r1][0]] = "(" + q[n[r1][0]];
        q[n[r1][1]] = q[n[r1][1]] + ")";
        int r2;
        while (true) {
          r2 = rand.nextInt(5);
          if (r2 != r1) {
            if (n[r1][0] != n[r2][1] && n[r1][1] != n[r2][0]) {
              break;
            }
          }
        }
        q[n[r2][0]] = "(" + q[n[r2][0]];
        q[n[r2][1]] = q[n[r2][1]] + ")";
      }
  • 合法性主要由if判断实现且主要体现在括号的选择上,由上面选取括号的代码可以分析出选择的逻辑,这里不再赘述。

  • 无重复性通过check函数实现,且该同学采用了一种特殊的方法——哈希码。计算得到每道生成的题的哈希码后再存入txt文件,比对时只需要比对哈希码的异同就行,降低了查重时的空间代价和时间代价。但是牺牲了生成题目时的时间消耗(需要进行额外的哈希码计算)

    for (int i = 1; i <= num; i++) {
      String Q1 = question();
      String H = String.valueOf(Q1.hashCode());
      String Q2 = i + ". " + Q1 + "\n\n";

      while (!check(H)) {
        Q1 = question();
        H = String.valueOf(Q1.hashCode());
        Q2 = i + ". " + Q1 + "\n\n";
      }

三、优缺点评价

优点:该同学代码书写规范,能够较好的将代码模块化,提高了代码的重用性和可维护性。并且运用算法的知识,通过哈希码来实现查重,比较有新意。

缺点:在临时变量的命名上不太合理,没有采用易于理解的命名而是一些单个的字母,给代码的阅读带来了一定的困难,希望下次能进行改善。

posted @ 2021-09-29 21:41  HNU散人  阅读(119)  评论(0编辑  收藏  举报