结对项目--实现括号和带分数的四则运算

项目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834/homework/11148
这个作业的目标 队友互相协作生成设计文档,实现代码编写和代码复审,最终实现一个可以处理括号和带分数的Java四则运算器

结对成员:

  • 姓名:刘奕池 学号:3118005285
  • 姓名:谢智杰 学号:3118005292

github地址

1. PSP表格

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

2. 计算模块接口的设计

  • entity包

    • 1.1 数值表示类:FractionNum, 该类支持分数和整数的存储。
  • controller包

    • 2.1 分数运算器:FraCalculator, 主要进行四则运算表达式的计算并返回一个FractionNum对象
    package com.my.controller;
    import com.my.entity.FractionNum;
    import java.util.Stack;
    /**
     * 计算器
     */
    public class FracCalculator {
        final public static FracCalculator calculator = new FracCalculator();
        /**
         * 符号栈:用于存储运算符和括号
         */
        private Stack<Character> symbolStack = null;
    
        /**
         * 解析并计算四则运算表达式(含括号),返回计算结果
         *
         * @param numStr 算术表达式(含括号)
         */
        public FractionNum calculate(String numStr) {
    
    //        System.out.println(new Throwable().getStackTrace()[0]+":"+numStr);
            numStr = removeStrSpace(numStr); // 去除空格
            // 如果算术表达式尾部没有‘=’号,则在尾部添加‘=’,表示结束符
            if (numStr.length() >= 1 && !"=".equals(numStr.charAt(numStr.length() - 1) + "")) {
                numStr += "=";
            }
            // 检查表达式是否合法
            if (!isStandard(numStr)) {
                System.out.println("错误:算术表达式有误!");
                return new FractionNum(0);
            }
            // 初始化栈
            /* 数字栈:用于存储表达式中的各个数字 */
            Stack<FractionNum> numberStack = new Stack<>();
            symbolStack = new Stack<>();
            // 用于缓存数字,因为数字可能是多位的
            StringBuffer temp = new StringBuffer();
            // 从表达式的第一个字符开始处理
            for (int i = 0; i < numStr.length(); i++) {
                // 获取一个字符
                char ch = numStr.charAt(i);
                if (isNumber(ch)) { // 若当前字符是数字
                    temp.append(ch); // 加入到数字缓存中
                } else { // 非数字的情况
                    String tempStr = temp.toString(); // 将数字缓存转为字符串
                    if (!tempStr.isEmpty()) {
                        int num = Integer.parseInt(tempStr); // 将数字字符串转为长整型数
                        numberStack.push(new FractionNum(num)); // 将数字压栈
                        temp = new StringBuffer(); // 重置数字缓存
                    }
                    // 判断运算符的优先级,若当前优先级低于栈顶的优先级,则先把计算前面计算出来
                    while (!comparePri(ch) && !symbolStack.empty()) {
                        FractionNum b = numberStack.pop(); // 出栈,取出数字,后进先出
                        FractionNum a = numberStack.pop();
                        // 取出运算符进行相应运算,并把结果压栈进行下一次运算
                        switch (symbolStack.pop()) {
                            case '’':
                                numberStack.push(FractionNum.with(a, b));
                                break;
                            case '+':
                                numberStack.push(FractionNum.add(a, b));
                                break;
                            case '-':
                                numberStack.push(FractionNum.sub(a, b));
                                break;
                            case '×':
                            case '*':
                                numberStack.push(FractionNum.mul(a, b));
                                break;
                            case '/':
                            case '÷':
                                numberStack.push(FractionNum.div(a, b));
                                break;
                            default:
                                break;
                        }
                    } // while循环结束
                    if (ch != '=') {
                        symbolStack.push(ch); // 符号入栈
                        if (ch == ')') { // 去括号
                            symbolStack.pop();
                            symbolStack.pop();
                        }
                    }
                }
            } // for循环结束
    
            return numberStack.pop(); // 返回计算结果
        }
    
        /**
         * 去除字符串中的所有空格
         */
        private String removeStrSpace(String str) {
            return str != null ? str.replaceAll(" ", "") : "";
        }
    
        /**
         * 检查算术表达式的基本合法性,符合返回true,否则false
         */
        private boolean isStandard(String numStr) {
            if (numStr == null || numStr.isEmpty()) // 表达式不能为空
                return false;
            Stack<Character> stack = new Stack<>(); // 用来保存括号,检查左右括号是否匹配
            boolean b = false; // 用来标记'='符号是否存在多个
            for (int i = 0; i < numStr.length(); i++) {
                char n = numStr.charAt(i);
                // 判断字符是否合法
                if (!(isNumber(n) || "(".equals(n + "") || ")".equals(n + "")
                        || "+".equals(n + "") || "-".equals(n + "")
                        || "*".equals(n + "") || "/".equals(n + "")
                        || "=".equals(n + "") || "÷".equals(n + "") || "×".equals(n + "") || "’".equals(n + ""))) {
                    return false;
                }
                // 将左括号压栈,用来给后面的右括号进行匹配
                if ("(".equals(n + "")) {
                    stack.push(n);
                }
                if (")".equals(n + "")) { // 匹配括号
                    if (stack.isEmpty() || !"(".equals((char) stack.pop() + "")) // 括号是否匹配
                        return false;
                }
                // 检查是否有多个'='号
                if ("=".equals(n + "")) {
                    if (b)
                        return false;
                    b = true;
                }
            }
            // 可能会有缺少右括号的情况
            if (!stack.isEmpty())
                return false;
            // 检查'='号是否不在末尾
            return "=".equals(numStr.charAt(numStr.length() - 1) + "");
        }
    
        /**
         * 判断字符是否是0-9的数字
         */
        private boolean isNumber(char num) {
            return num >= '0' && num <= '9';
        }
    
        /**
         * 比较优先级:如果当前运算符比栈顶元素运算符优先级高则返回true,否则返回false
         */
        private boolean comparePri(char symbol) {
            if (symbolStack.empty()) { // 空栈返回ture
                return true;
            }
    
            // 符号优先级说明(从高到低):
            // 第1级: (
            // 第2级: * /
            // 第3级: + -
            // 第4级: )
    
            char top = symbolStack.peek(); // 查看堆栈顶部的对象,注意不是出栈
            if (top == '(') {
                return true;
            }
            // 比较优先级
            switch (symbol) {
                case '(': // 优先级最高
                    return true;
                case '/':
                    return true;
                case '’':
                    // 优先级比+和-高
                    return top == '+' || top == '-' || top == '×' || top == '÷' || top == '*';
                case '×':
                case '*':
                case '÷': {
                    // 优先级比+和-高
                    return top == '+' || top == '-';
                }
                case '+':
                case '-':
                    return false;
                case ')': // 优先级最低
                    return false;
                case '=': // 结束符
                    return false;
                default:
                    break;
            }
            return true;
        }
    }
    
    • 2.2 数值运算器:Calculator, 一个简单的数值运算器,主要用于对分数运算器返回的FractionNum结果进行运算,判断结果的正负。
      • FractionNumCalculate(fractionNum1,fractionNum2)
      • calculate(String str)方法
    package com.my.controller;
    import com.my.entity.FractionNum;
    import java.util.Stack;
    
    public class Calculator {
        private static final Stack<Character> stack;//后缀表达式
        private static final Stack<Character> stack_1;//符号栈
        private static final Stack<Character> stack_2;//临时栈
    
        static {
            stack = new Stack<>();
            stack_1 = new Stack<>();
            stack_2 = new Stack<>();
        }
    
        //运算
        public static Double calculate(String str) throws Exception {
            char[] arr = str.toCharArray();
            //转化为后缀表达式
            for (char c : arr) {
                if (Character.isDigit(c)) {//判断是否为数字
                    stack.push(c);
                } else if (c == '*' || c == '/') {
                    while (!stack_1.empty()) {
                        char ch = stack_1.pop();
                        if (ch == '(') {
                            stack_1.push(ch);
                            break;
                        } else if (ch == '*' || ch == '/') {
                            stack.push(ch);
                        } else {
                            stack_2.push(ch);
                        }
                    }
                    while (!stack_2.empty()) {
                        stack_1.push(stack_2.pop());
                    }
                    stack_1.push(c);
                } else if (c == '+' || c == '-') {
                    while (!stack_1.empty()) {
                        char ch = stack_1.pop();
                        if (ch == '(') {
                            stack_1.push(ch);
                            break;
                        } else if (ch == '*' || ch == '/' || ch == '+' || ch == '-') {
                            stack.push(ch);
                        } else {
                            stack_2.push(ch);
                        }
                    }
                    while (!stack_2.empty()) {
                        stack_1.push(stack_2.pop());
                    }
                    stack_1.push(c);
                } else if (c == '(') {
                    stack_1.push(c);
                } else if (c == ')') {
                    char ch = stack_1.peek();
                    while (ch != '(') {
                        ch = stack_1.pop();
                        stack.push(ch);
                    }
                    stack.pop();
                } else {
                    throw new Exception();
                }
            }
            while (!stack_1.empty()) {
                stack.push(stack_1.pop());
            }
            //进行运算
            int index = 0;
            while (!stack.empty()) {
                index++;
                stack_2.push(stack.pop());
            }
            Stack<Double> s = new Stack<>();//用于最后计算的栈
            while (!stack_2.empty()) {
                char ch = stack_2.pop();
                if (index > 1) {
                    if (ch == '*' || ch == '/' || ch == '+' || ch == '-') {
                        double sum = 0;
                        double num1 = s.pop();
                        double num2 = s.pop();
                        switch (ch) {
                            case '*':
                                sum = num2 * num1;
                                break;
                            case '/':
                                sum = num2 / num1;
                                break;
                            case '+':
                                sum = num2 + num1;
                                break;
                            case '-':
                                sum = num2 - num1;
                                break;
                        }
                        s.push(sum);
                    } else if (Character.isDigit(ch)) {
                        s.push((double) Character.getNumericValue(ch));
                    } else {
                        throw new Exception();
                    }
                } else {
                    s.push((double) Character.getNumericValue(ch));
                    break;
                }
            }
            return s.pop();
        }
    
        /**
         * 带分数比较
         * @param num1 带分数1
         * @param num2 带分数2
         * @return false表示前一个值比另一个值大,true表示后者比前者大
         */
        public static boolean FractionNumCalculate(FractionNum num1, FractionNum num2) throws Exception {
            //false表示前一个值比另一个值大,true表示后者比前者大
            int num1Index1 = num1.toString().indexOf('’');
            int num2Index1 = num2.toString().indexOf('’');
            if (num1Index1 != -1 || num2Index1 != -1) {
                if (num1Index1 == -1) {//3和2’1/3
                    Double answer1 = Calculator.calculate(num1.toString());
                    Double answer2 = Calculator.calculate(num2.toString().substring(0, num2Index1));
                    return answer1 <= answer2;
                } else if (num2Index1 == -1) {//2’1/3和3
                    Double answer1 = Calculator.calculate(num1.toString().substring(0, num1Index1));
                    Double answer2 = Calculator.calculate(num2.toString());
                    return answer1 <= answer2;
                } else {//2’1/3和3‘1/3
                    if (num1Index1 >= num2Index1) {
                        Double answer1 = Calculator.calculate(num1.toString().substring(0, num1Index1));
                        Double answer2 = Calculator.calculate(num2.toString().substring(0, num2Index1));
                        if (answer1 > answer2) {//分数前的数值比较,前者大返回false
                            return false;
                        }
                        if (answer1 < answer2) {//分数前的数值比较,前者大返回true
                            return true;
                        } else {
                            answer1 = Calculator.calculate(num1.toString().substring(num1Index1 + 1));
                            answer2 = Calculator.calculate(num2.toString().substring(num2Index1 + 1));
                            return answer1 <= answer2;
                        }
                    } else {
                        //后一个分数的数值更大
                        return true;
                    }
                }
    
            } else {
                try {
    
                    Double answer1 = calculate(num1.toString());
                    Double answer2 = calculate(num2.toString());
                    return answer1 <= answer2;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return false;
            }
        }
    
    
    }
    
    • 2.3 式子生成器:CreatFormula, 主要用于生成四则运算式子并检验式子是否符合要求,
      • String createProblem(int maxNum) 生成四则运算式子
      • int[] index(int n) 产生操作符的下标数组
      • String check(String str, int operatorNum, int[] arr, FractionNum[] number, String[] operator, int flag) 检验式子是否正确
      • String compare(String str1, String str2) 式子前后的数值做比较
    package com.my.controller;
    import com.my.entity.FractionNum;
    import java.util.Random;
    public class CreateFormula {
        public static final String True = "true";
        public static final String False = "false";
        public static final String Error = "error";
    
        /**
         * 生成四则运算式子
         * @param maxNum    式子中的数值的最大值
         * @return          返回一个不超三个运算符的四则运算式子
         * @throws Exception 抛出异常
         */
        public static String createProblem(int maxNum) throws Exception {  //产生整数式子
            Random r = new Random();
            // 操作符数值
            String[] operator = {"+", "-", "*", "÷"};
            // 随机生成操作符的个数1, 2
            int operatorNum = 1 + r.nextInt(2);
            // 新建数组来保存操作数
            FractionNum[] number = new FractionNum[operatorNum + 1];
    
            //操作符的下标
            int[] arr = index(operatorNum);
            String s = "";
            /* 通过循环和判断获取四则运算式子的所有操作数 */
            for (int j = 0; j < operatorNum + 1; j++) {
                int num1 = r.nextInt(maxNum);
    //            int num2 = 10 - num1;
                int num2 ;
                int flag = r.nextInt(3);//0为整数, 1为分数, 2为带分数
                FractionNum num;
                if (flag == 0) {  // 整数处理
                    if(num1 > maxNum){
                        j--;
                        continue;
                    }
                    num = new FractionNum(num1);
                } else {
                    if(flag == 1){  // 分数处理
                        num2 =1 + r.nextInt(maxNum - 1);
                    } else {  // 带分数处理
                        num2 = maxNum + r.nextInt(maxNum);
                    }
                    if((num1/num2) >= maxNum ){  // 保证数值不超过范围
                        j--;
                        continue;
                    }
                    num = new FractionNum(num1, num2);
                }
                number[j] = num;
            }
    
            //如果flag=0,则该式子加左括号,如果flag=1,则该式子加右括号,2为无括号
            int flag = r.nextInt(3);
    //        int flag = 1;
            switch (operatorNum) {
                case 1: {
                    s = number[0] + operator[arr[0]] + number[1];
                    break;
                }
                case 2: {
                    if (flag == 0) {
                        s = "(" + number[0] + operator[arr[0]] + number[1] + ")" + operator[arr[1]] + number[2];
                    } else if (flag == 1) {
                        s = number[0] + operator[arr[0]] + "(" + number[1] + operator[arr[1]] + number[2] + ")";
                    } else {
                        s = number[0] + operator[arr[0]] + number[1] + operator[arr[1]] + number[2];
                    }
                    break;
                }
                default:
                    break;
            }
            s = CreateFormula.check(s, operatorNum, arr, number, operator, flag);
            if ("The formula is error".equals(s)) {
                return createProblem(maxNum);
            }
            FractionNum num = FracCalculator.calculator.calculate(s);
            int answer = num.getNumerator();
            if (answer >= 0) {
                s = s + "=";
            } else {
                return createProblem(maxNum);
            }
            return s;
    
        }
    
        /**
         * 产生操作符的下标数组
         *
         * @param n 下标数组的位数
         * @return 返回下标数组
         */
        public static int[] index(int n) { //产生操作符的下标数组
            Random random = new Random();
            int[] a = new int[n];
            for (int j = 0; j < n; j++) {
                a[j] = random.nextInt(4);
            }
            return a;
        }
    
        /**
         * 检验式子是否正确
         *
         * @param str         第一次生成式子
         * @param operatorNum 获取相应的操作符个数1-2
         * @param arr         操作符下标,0表示+,1表示-,2表示*,3表示÷
         * @param number      数字数组
         * @param operator    +-*÷数组
         * @return 经过判断和处理后,如果式子内容没有问题,则返回更改后的式子,式子有问题则返回"The formula is error"
         */
        public static String check(String str, int operatorNum, int[] arr, FractionNum[] number, String[] operator, int flag) throws Exception {
    
            for (int i = 0; i < operatorNum; i++) {
                // 检测出当前操作符为-号
                if (arr[i] == 1) {
                    // 操作符的个数不唯一
                    if (operatorNum != 1) {
                        String str1;
                        String str2;
                        // -号为第一个运算符
                        if (i == 0) {
                            // -号为第一个运算符且为左括号的情况
                            if (flag == 0) {
                                //  其中一个操作数出现负号
                                if ("error".equals(compare(number[0].toString(), number[1].toString()))) {
                                    str = "The formula is error";
                                }
                                // 后操作数比前操作数大
                                if ("true".equals(compare(number[0].toString(), number[1].toString()))) {
                                    FractionNum temp = number[0];
                                    number[0] = number[1];
                                    number[1] = temp;
                                    str = "(" + number[0] + operator[arr[0]] + number[1] + ")" + operator[arr[1]] + number[2];
                                }
                            }
    
                            // -号为第一个运算符且为右括号的情况
                            if (flag == 1) {
                                str1 = "" + number[0];
                                str2 = "(" + number[1] + operator[arr[1]] + number[2] + ")";
                                //  其中一个操作数出现负号
                                if ("error".equals(compare(str1, str2))) {
                                    str = "The formula is error";
                                }
                                // 后操作数比前操作数大
                                if ("true".equals(compare(str1, str2))) {
                                    str = str2 + operator[arr[i]] + str1;
                                }
                            } else {
                                str1 = "" + number[0];
                                str2 = number[1] + operator[arr[1]] + number[2];
                                //  其中一个操作数出现负号
                                if ("error".equals(compare(str1, str2))) {
                                    str = "The formula is error";
                                }
                                // 后操作数比前操作数大
                                if ("true".equals(compare(str1, str2))) {
                                    str = str2 + operator[arr[i]] + str1;
                                }
                            }
                        } else {//第二个运算符为-号
                            // 第二个操作符为-号, 且为左括号情况
                            if (flag == 0) {
                                str1 = "(" + number[0] + operator[arr[0]] + number[1] + ")";
                                str2 = "" + number[2];
                                //  其中一个操作数出现负号
                                if ("error".equals(compare(str1, str2))) {
                                    str = "The formula is error";
                                }
                                // 后操作数比前操作数大
                                if ("true".equals(compare(str1, str2))) {
                                    str = str2 + operator[arr[i]] + str1;
                                }
                            }
    
                            // 第二个操作符为-号, 且为右括号情况
                            if (flag == 1) {
                                //  其中一个操作数出现负号
                                if ("error".equals(compare(number[1] + "", number[2] + ""))) {
                                    str = "The formula is error";
                                }
                                // 后操作数比前操作数大
                                if ("true".equals(compare(number[1] + "", number[2] + ""))) {
                                    FractionNum temp = number[1];
                                    number[1] = number[2];
                                    number[2] = temp;
                                    str = number[0] + operator[arr[0]] + "(" + number[1] + operator[arr[1]] + number[2] + ")";
                                }
                            } else {
                                str1 = number[0] + operator[arr[0]] + number[1];
                                str2 = "" + number[2];
                                //  其中一个操作数出现负号
                                if ("error".equals(compare(str1, str2))) {
                                    str = "The formula is error";
                                }
                                // 后操作数比前操作数大
                                if ("true".equals(compare(str1, str2))) {
                                    str = str2 + operator[arr[i]] + str1;
                                }
                            }
                        }
                    } else {
                        FractionNum temp;
                        /* 式子只有一个操作符且操作符为-号, 先比较-号前后的两个数字, 若后者比前者大则数字的顺序颠倒 */
                        if (Calculator.FractionNumCalculate(number[0], number[1])) {
                            temp = number[0];
                            number[0] = number[1];
                            number[1] = temp;
                            str = number[0] + "-" + number[1];
                        }
                    }
                }
    
                // 检测到操作符为÷号
                if (arr[i] == 3) {
                    // 操作符为÷号且只有一个操作符
                    if (operatorNum == 1) {
                        /* 判断÷号后面的数字是否为0, 如果为0就把其改为1 */
                        number[1] = (number[1].getNumerator() == 0) ? new FractionNum(1) : number[1];
                        str = number[0] + operator[arr[0]] + number[1];
                    } else {
                        /* 判断÷号后面的数字是否为0, 如果为0就把其改为1 */
                        number[i + 1] = (number[i + 1].getNumerator() == 0) ? new FractionNum(1) : number[i + 1];
                        if (flag == 0) {  // 判断式子是否为左括号情况
                            str = "(" + number[0] + operator[arr[0]] + number[1] + ")" + operator[arr[1]] + number[2];
                        } else {  // 式子为右括号或者无括号
                            str = number[0] + operator[arr[0]] + number[1] + operator[arr[1]] + number[2];
                        }
                    }
                }
            }
    //        System.out.println(str);
            return str;
        }
    
        /**
         * 式子前后的数值做比较
         * @param str1 -号式子的左半部
         * @param str2 -号式子的右半部
         * @return 返回一个boolean类型的值,false表示左半部值比右半部值大,true表示后者比前者大
         */
        public static String compare(String str1, String str2) {
            //false表示前一个值比另一个值大,true表示后者比前者大
            try {
                /*调用CalculatorT.calculator.calculate()方法实现带分数的运算器计算,返回一个FractionNum带分数类型*/
                FractionNum num1 = FracCalculator.calculator.calculate(str1);
                FractionNum num2 = FracCalculator.calculator.calculate(str2);
                if (isNormal(num1) && isNormal(num2)) {
                    if (Calculator.FractionNumCalculate(num1, num2)) {
                        return True;
                    }
                } else {
                    return Error;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return False;
        }
    
        /**
         * 判断分数内容是否正常,即是否出现负数的分子分母
         * @param num 带分数
         * @return 如果带分数的分子分母存在负数则返回false, 否则返回true
         */
        public static boolean isNormal(FractionNum num) {
            return num.getDenominator() >= 0 && num.getNumerator() >= 0;
        }
    }
    
    
    • 2.4 四则运算平台:CalculatePlatform, 运行四则运算平台, 调用其余三个controller包下的方法实现完整的运算流程, 内含运行四则计算器平台方法runPlatform()。
      • void runPlatform(int num,int maxNum) 运行四则计算器平台
    package com.my.controller;
    import com.my.entity.FractionNum;
    import com.my.util.ReadTxt;
    import java.util.Scanner;
    
    public class CalculatePlatform {
        /**
         * 运行四则计算器平台
         * @param num       生成四则运算式子的个数
         * @param maxNum    数值允许范围的最大值
         * @throws Exception 抛出异常
         */
        public static void runPlatform(int num,int maxNum) throws Exception {
            Scanner scanner = new Scanner(System.in);
            StringBuilder exercisesBuffer = new StringBuilder();    // 练习题目buffer
            StringBuilder answerBuffer = new StringBuilder();       // 练习答案buff
            StringBuilder correctBuffer = new StringBuilder();      // 正确答案buff
            StringBuilder wrongBuffer = new StringBuilder();        // 错误答案buff
            String[] officialAnswer = new String[num];              // 练习答案, 用于逐个与用户输入答案做比较
            int[] userAnswerIndex = new int[num];                   // int数组, 0表示答案有误, 1表示答案正确
    
            String userAnswer;                                      // 暂存用户输入答案
            int correctNum = 0;                                     // 回答正确题目个数
            int wrongNum = 0;                                       // 回答错误题目个数
    
            for (int i = 0; i < num; i++) {
                // 生成式子
                String str = CreateFormula.createProblem(maxNum);
                System.out.println(str);
                // 把每一次生成的式子存入exercisesBuffer
                exercisesBuffer.append("第").append(i + 1).append("题:").append(str).append("\r\n--------------------\r\n");
                // 获取式子运算结果
                FractionNum answerNum = FracCalculator.calculator.calculate(str);
                // 保存结果答案
                officialAnswer[i] = answerNum.toString();
    
                /* 用户逐题输入式子的结果 */
                userAnswer = scanner.next();
                if(officialAnswer[i].equals(userAnswer)){
                    userAnswerIndex[i] = 1;
                    correctNum++;
                } else {
                    userAnswerIndex[i] = 0;
                    wrongNum++;
                }
    
                // 把每一次生成的答案存入answerBuffer
                answerBuffer.append("第").append(i + 1).append("题答案:").append(answerNum.toString()).append("\n").append("--------------------\n");
                System.out.println("--------------------");
    
                // 最后一个式子生成完毕, 把exercisesBuffer和answerBuffer内容存入相应文档
                if(i == num -1){
                    ReadTxt.writeTxt("C:\\Users\\10973\\Desktop\\test\\Exercises.txt",exercisesBuffer.toString());
                    ReadTxt.writeTxt("C:\\Users\\10973\\Desktop\\test\\Answers.txt",answerBuffer.toString());
                }
            }
    
            // 统计用户的答题情况
            correctBuffer.append("Correct:").append(correctNum).append("(");
            wrongBuffer.append("Wrong:").append(wrongNum).append("(");
            for (int i = 0; i < num; i++){
                if(userAnswerIndex[i] == 1){
                    correctBuffer.append((i+1)).append(", ");
                } else {
                    wrongBuffer.append((i+1)).append(", ");
                }
                if(i == (num - 1)){
                    correctBuffer.append(")");
                    wrongBuffer.append(")");
                }
            }
            // 把用户答题情况保存到文档中
            ReadTxt.writeTxt("C:\\Users\\10973\\Desktop\\test\\Grade.txt",
                    correctBuffer.toString() + "\r\n" + wrongBuffer.toString());
        }
    }
    
  • ** util包**

    • 3.1 文件读取工具:ReadTxt, 主要功能是实现文件的读取和写入.
      • void readTxt(String txtPath) 读取路径
      • void writeTxt(String txtPath,String content) 把内容写入文件
  • 程序类图

  • 部分代码流程图

3. 程序性能分析

  • 性能分析截图

  • 内存空间占用

4. 计算模块部分单元测试展示

  • 测试生成10000条式子

  • 部分结果展示:

  • 文本内容展示:

posted @ 2020-10-10 22:20  流逝时光Z  阅读(510)  评论(0)    收藏  举报