结对项目

结对项目

课程链接 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34
作业要求 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230
作业目标 实现四则运算程序,掌握结对合作完成项目的技巧
成员1 沈思敏 3122004877
成员2 郑灿嘉 3122004887

github地址

https://github.com/SiMON-Shen11/FormulCalculate

PSP表格

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

程序结构及效能分析

式子生成—代码覆盖率

式子生成—方法调用频率、内存分配

答案检查—代码覆盖率

答案检查—方法调用频率、内存分配

代码说明

MyApp类实现输入、输出

`public static void creatFormalu() {
    System.out.print("请输入生成的题目数:");
    int num = scanner.nextInt();
    System.out.print("请输入生成的最大的数值:");
    int max = scanner.nextInt();
    UtilClass.deleteFile("Exercises.txt");
    UtilClass.deleteFile("Answers.txt");
    FormulaBuilder.startCreate(num, max);
    System.out.print("题目生成完毕");
}

public static void checkFormula() {
    System.out.print("请输入Exercises.txt的文件路径:");
    String exePath = scanner.next();
    System.out.print("请输入Answers.txt文件路径:");
    String workPath = scanner.next();
    UtilClass.deleteFile("Correct.txt");
    UtilClass.deleteFile("Grade.txt");
    FormulaBuilder.startCheck(exePath, workPath);
    System.out.print("答案校对完毕");
}`

UtilClasss类

LCM求公倍数
      public static int GCD(int first, int second) {
    int remainder;
    if (first < second) {
        remainder = first;
        first = second;
        second = remainder;
    }

  for(remainder = first % second; remainder != 0; remainder = first % remainder) {
        first = second;
        second = remainder;
    }

    return second;
}
public static int LCM(int first, int second) {
    int gcd = GCD(first, second);
    return first * second / gcd;
}`
中缀后缀表达式求值

`

public static String trunToSuffixString(String infixString) {
    String[] split = infixString.split(" ");
    List<String> list = new ArrayList();
    String[] var3 = split;
    int var4 = split.length;
    String item;
    for(int var5 = 0; var5 < var4; ++var5) {
        item = var3[var5];
        list.add(item);
    }
    Stack<String> s1 = new Stack();
         List<String> s2 = new ArrayList();
         Iterator var10 = list.iterator(); while(true) {
        while(var10.hasNext()) {
            item = (String)var10.next();
            if (isElement(item)) {
                s2.add(item);
            } else if (item.equals("(")) {
                s1.push(item);
            } else if (item.equals(")")) {
                while(!((String)s1.peek()).equals("(")) {
                    s2.add((String)s1.pop());
                }

                s1.pop();
            } else {
                while(!s1.empty() && UtilClass.Operation.getPrio(item) <= UtilClass.Operation.getPrio((String)s1.peek())) {
                    s2.add((String)s1.pop());
                }

                s1.push(item);
            }
        }

        while(!s1.empty()) {
            s2.add((String)s1.pop());
        }

        String suffixString = new String();

        String item;
        for(Iterator var12 = s2.iterator(); var12.hasNext(); suffixString = suffixString + item + " ") {
            item = (String)var12.next();
        }

        return suffixString;
    }
}

public static String getResult(String suffixString) {
    String[] split = suffixString.split(" ");
    List<String> list = new ArrayList();
    String[] var3 = split;
    int var4 = split.length;

    for(int var5 = 0; var5 < var4; ++var5) {
        String ele = var3[var5];
        list.add(ele);
    }

    Stack<String> stack = new Stack();
    Iterator var10 = list.iterator();

    while(var10.hasNext()) {
        String item = (String)var10.next();
        if (isElement(item)) {
            stack.push(item);
        } else {
            Element num2 = Element.parseElement((String)stack.pop());
            Element num1 = Element.parseElement((String)stack.pop());
            String res = null;
            if (item.equals("+")) {
                res = num1.add(num2).toString();
            } else if (item.equals("-")) {
                res = num1.sub(num2).toString();
            } else if (item.equals("×")) {
                res = num1.mul(num2).toString();
            } else if (item.equals("÷")) {
                res = num1.div(num2).toString();
            } else {
                System.out.println("运算符输入错误");
            }

            stack.push(res);
        }
    }

    return (String)stack.pop();
}`
标准化输出答案

`

 public static String standard(String firstResult) {
    Element element = Element.parseElement(firstResult);
    if (element.isDivision()) {
        if (element.getDowm() == 0 || element.getUp() == 0) {
            return "0";
        }

        int times;
        if (element.getUp() != 0 && GCD(element.getUp(), element.getDowm()) != 1) {
            times = GCD(element.getUp(), element.getDowm());
            element.setUp(element.getUp() / times);
            element.setDowm(element.getDowm() / times);
        }

        if (element.getUp() * element.getDowm() < 0 && element.getUp() > 0) {
            element.setUp(element.getUp() * -1);
            element.setDowm(element.getDowm() * -1);
        }

        if (element.getUp() >= element.getDowm()) {
            times = element.getUp() / element.getDowm();
            element.setUp(element.getUp() - times * element.getDowm());
            if (element.getUp() == 0) {
                return "" + times;
            }

            return "" + times + "'" + element.toString();
        }

        if (element.getDowm() == 1) {
            element.setDivision(false);
        }
    }

    return element.toString();
}  

`

FormulaBuilder类执行运算式子的生成和修饰

`

public class FormulaBuilder {
private static Random random = new Random();
private static StringBuilder sb = new StringBuilder(64);

public FormulaBuilder() {
}

public static void startCreate(int num, int max) {
    Formula[] formulas = new Formula[num];

    for(int i = 0; i < num; ++i) {
        Formula sigleFormula = new Formula(max);
        UtilClass.wirteTxt("Exercises.txt", sigleFormula.getSb().toString() + "\n");
        UtilClass.wirteTxt("Answers.txt", i + 1 + "." + sigleFormula.getResult() + "\n");
    }

}

public static void startCheck(String exePath, String workPath) {
    String exeString = UtilClass.readTxt(exePath);
    String[] exeSpilt = exeString.split(" =");
    exeSpilt[0] = exeSpilt[0].replace("null", "");
    int index = 1;
    String[] var6 = exeSpilt;
    int var7 = exeSpilt.length;

    for(int var8 = 0; var8 < var7; ++var8) {
        String item = var6[var8];
        String record = UtilClass.standard(UtilClass.getResult(UtilClass.trunToSuffixString(item)));
        int var10001 = index++;
        UtilClass.wirteTxt("Correct.txt", "" + var10001 + "." + record + "\n");
    }

    String ansString = UtilClass.readTxt(workPath);
    String[] ansSpilt = ansString.split("[.]");
    String corString = UtilClass.readTxt("Correct.txt");
    String[] corSpilt = corString.split("[.]");
    List<Integer> rightList = new ArrayList();
    List<Integer> wrongList = new ArrayList();

    for(int i = 1; i < corSpilt.length; ++i) {
        if (ansSpilt[i].equals(corSpilt[i])) {
            rightList.add(i);
        } else {
            wrongList.add(i);
        }
    }

    String gradeContent;
    for(gradeContent = "Correct:" + rightList.size() + " ("; !rightList.isEmpty(); gradeContent = gradeContent + String.valueOf(rightList.remove(0)) + ",") {
    }

    if (gradeContent.charAt(gradeContent.length() - 1) == ',') {
        gradeContent = gradeContent.substring(0, gradeContent.length() - 1);
    }

    for(gradeContent = gradeContent + ")\nWrong: " + wrongList.size() + " ("; !wrongList.isEmpty(); gradeContent = gradeContent + String.valueOf(wrongList.remove(0)) + ",") {
    }

    if (gradeContent.charAt(gradeContent.length() - 1) == ',') {
        gradeContent = gradeContent.substring(0, gradeContent.length() - 1);
    }

    gradeContent = gradeContent + ")";
    UtilClass.wirteTxt("Grade.txt", gradeContent);
}

}
`

Element类管理分数并提供相应计算方法

`

public class Element {
private boolean isDivision = false;
private static Random random = new Random();
private int max;
private int up;
private int dowm = -1;

public Element() {
}

public Element(boolean isDivision, int max) {
    this.isDivision = isDivision;
    this.max = max;
    if (isDivision) {
        this.dowm = random.nextInt(max - 2) + 2;
        this.up = random.nextInt(this.dowm - 1) + 1;
    } else {
        this.dowm = -1;
        this.up = random.nextInt(max - 1) + 1;
    }

}

public Element add(Element anotherElement) {
    if (this.isDivision && anotherElement.isDivision) {
        try {
            int sameDown = UtilClass.LCM(this.getDowm(), anotherElement.getDowm());
            this.up = this.up * sameDown / this.dowm;
            this.dowm = sameDown;
            anotherElement.up = anotherElement.up * sameDown / anotherElement.dowm;
            anotherElement.dowm = sameDown;
        } catch (Exception var3) {
            PrintStream var10000 = System.out;
            int var10001 = this.getDowm();
            var10000.println("" + var10001 + "  " + anotherElement.getDowm());
        }

        this.up += anotherElement.up;
        return this;
    } else if (!this.isDivision && !anotherElement.isDivision) {
        this.up += anotherElement.up;
        return this;
    } else if (this.isDivision) {
        this.up += anotherElement.up * this.dowm;
        return this;
    } else {
        anotherElement.up += this.up * anotherElement.dowm;
        return anotherElement;
    }
}

public Element sub(Element anotherElement) {
    if (this.isDivision && anotherElement.isDivision) {
        try {
            int sameDown = UtilClass.LCM(this.getDowm(), anotherElement.getDowm());
            this.up = this.up * sameDown / this.dowm;
            this.dowm = sameDown;
            anotherElement.up = anotherElement.up * sameDown / anotherElement.dowm;
            anotherElement.dowm = sameDown;
        } catch (Exception var3) {
            PrintStream var10000 = System.out;
            int var10001 = this.getDowm();
            var10000.println("" + var10001 + "  " + anotherElement.getDowm());
        }

        this.up -= anotherElement.up;
        return this;
    } else if (!this.isDivision && !anotherElement.isDivision) {
        this.up -= anotherElement.up;
        return this;
    } else if (this.isDivision) {
        this.up -= anotherElement.up * this.dowm;
        return this;
    } else {
        this.isDivision = true;
        this.up = this.up * anotherElement.dowm - anotherElement.up;
        this.dowm = anotherElement.dowm;
        return this;
    }
}

public Element mul(Element anotherElement) {
    if (this.isDivision && anotherElement.isDivision) {
        this.up *= anotherElement.up;
        this.dowm *= anotherElement.dowm;
        return this;
    } else if (!this.isDivision && !anotherElement.isDivision) {
        this.up *= anotherElement.up;
        return this;
    } else if (this.isDivision) {
        this.up *= anotherElement.up;
        return this;
    } else {
        anotherElement.up *= this.up;
        return anotherElement;
    }
}

public Element div(Element anotherElement) {
    if (this.isDivision && anotherElement.isDivision) {
        this.up *= anotherElement.dowm;
        this.dowm *= anotherElement.up;
        return this;
    } else if (!this.isDivision && !anotherElement.isDivision) {
        this.isDivision = true;
        this.dowm = anotherElement.up;
        return this;
    } else if (this.isDivision) {
        this.dowm *= anotherElement.up;
        return this;
    } else {
        anotherElement.dowm *= this.up;
        return anotherElement;
    }
}

public static Element parseElement(String str) {
    Element ele = new Element();
    if (str.matches("-?\\d+/-?\\d+")) {
        ele.isDivision = true;
        String[] split = str.split("/");
        ele.up = Integer.parseInt(split[0]);
        ele.dowm = Integer.parseInt(split[1]);
    } else {
        ele.isDivision = false;
        ele.up = Integer.parseInt(str);
    }

    return ele;
}

public String toString() {
    return this.isDivision ? this.up + "/" + this.dowm : "" + this.up;
}

public int getMax() {
    return this.max;
}

public void setMax(int max) {
    this.max = max;
}

public int getUp() {
    return this.up;
}

public void setUp(int up) {
    this.up = up;
}

public int getDowm() {
    return this.dowm;
}

public void setDowm(int dowm) {
    this.dowm = dowm;
}

public boolean isDivision() {
    return this.isDivision;
}

public void setDivision(boolean division) {
    this.isDivision = division;
}

}
`

测试运行结果

题目及答案


项目总结

  • 在本项目中,我们成功实现了一个命令行程序,能够根据用户指定的数量和范围自动生成小学四则运算题目,并记录相关答案。程序功能完整,确保题目计算过程不产生负数,设计了用户友好的命令行参数,使得生成过程简便高效。此外,题目和答案被有效存储在文本文件中,便于阅卷和统计,增强了程序的可扩展性,满足了不同用户的需求。
  • 在实施过程中,我们遇到了一些挑战,包括逻辑复杂性、性能优化的时间消耗和团队协作的挑战。通过有效的沟通和代码审查,我们克服了这些问题,提升了工作效率。此次经历不仅增强了我们的编程能力,也让我们认识到良好沟通、合理时间管理和关注细节的重要性。未来,我们将继续保持这种合作精神,追求更高的项目质量。
posted @ 2024-09-28 18:06  SimonShen01  阅读(8)  评论(0编辑  收藏  举报