kevin-

导航

结对项目-四则运算

这个作业属于哪个课程 计科22级12班
这个作业要求在哪里 作业
这个作业的目标 与队友合作生成一个能够实现小学四则运算的程序

Github链接


一、队员信息

柯锦宏 3122004910
陈煜 3122004904

2、PSP表格

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

3模块设计

3.1、设计实现过程

AnswerValidator类
读取题目和用户的答案文件,并比较它们,确定每道题的答案是正确还是错误,然后将结果写入成绩文件。

  • validateAnswers()方法:用于处理答案验证的逻辑。

ProducerController类
根据用户输入的设置生成指定数量的四则运算题目(包括整数和分数),并将题目和答案输出到两个文本文件中。

  • inputProblemSettings()方法:用于接收用户输入并进行验证。
  • generateArithmeticProblem(int numberOfProblems, int maxRange)方法:生成题目并输出到文件。

CreateFraction类
生成包含加法和减法的真分数表达式,并计算出对应的结果。

  • createFractionProblem(int range):生成真分数表达式和结果。

CreateInteger类
生成包含加法、减法、乘法和除法的随机整数表达式,并计算出结果。
-输入-:一个整数 range,用于限定生成的随机数范围。
-输出-:一个字符串数组,包含生成的数学表达式和计算结果。

  • createIntegerProblem(int range):生成数学表达式和计算结果。

  • indexOfOperator(int operatorCount, int operatorTypes, Random random):生成随机操作符的下标。

  • stitchingFormula(int operatorCount, int[] operand, int[] operatorIndex):拼接数学表达式。

  • algorithm(String s):计算给定表达式的值。

  • performSingleOperation(int a, int b, String operator):执行单个操作符的运算。

FileUtil类
为一个测验或考试应用提供基本的方法,管理练习题和答案,记录成绩,并有效地输出结果。它强调可读性和可维护性,同时确保文件操作的基本错误处理。

  • readExerciseFile(String path):读取格式为 "题目=答案" 的题目文件。

  • readAnswerFile(String path):读取格式为 "题目 答案" 的答案文件。

  • writeGradeFile(List correct, List wrong):将正确和错误的答案结果写入名为 "Grade.txt" 的文件。

  • outputFile(int index, String[] problem, PrintStream... streams):将题目和对应的答案输出到两个提供的 PrintStream 对象(例如控制台、文件)。

Math类
分别用于计算最大公因数、生成互质数对以及将假分数转换为真分数。

  • greatFactor_GCD(int x, int y):使用辗转相除法(欧几里得算法)计算两个整数 x 和 y 的最大公因数(GCD)。

  • createCoprimeNumbers(int range, Random random):生成一对互质数(即最大公因数为 1 的两个数)。

  • shamToProperFraction(int x, int y):将假分数(分子大于分母的分数)转换为真分数或带分数形式。

3.2、类的设计流程图:

MODEL类设计:

Controller类设计:

Util类设计:

4代码具体实现

  • AnswerValidator类
点击查看代码
public class AnswerValidator {

    // 启动方法,开始验证答案的过程
    public void validateAnswers() {
        FileUtil fileUtil = new FileUtil();
        Scanner scanner = new Scanner(System.in);

        // 提示用户输入题目文件路径
        System.out.print("请输入题目文件路径:");
        String exerciseFilePath = scanner.next();

        // 提示用户输入待验证答案文件路径
        System.out.print("请输入待验证答案文件路径:");
        String answerFilePath = scanner.next();

        try {
            // 读取题目文件和答案文件
            List<String> exercises = fileUtil.readExerciseFile(exerciseFilePath);
            List<String> answers = fileUtil.readAnswerFile(answerFilePath);

            // 存储正确和错误的题目编号
            List<String> correctAnswers = new ArrayList<>();
            List<String> incorrectAnswers = new ArrayList<>();

            // 获取最小答案数量以避免越界
            int min = Math.min(exercises.size(), answers.size());
            int num = 1;
            for (int i = 0; i < min; i++){
                if (exercises.get(i).equals(answers.get(i))){
                    correctAnswers.add(String.valueOf(num++));
                }else {
                    incorrectAnswers.add(String.valueOf(num++));
                }
            }

            // 写入成绩文件
            fileUtil.writeGradeFile(correctAnswers, incorrectAnswers);
            // 完成判定后输出信息
            System.out.println("判定完成");

        } catch (FileNotFoundException e) {
            System.out.println("文件不存在");
        } catch (IOException e) {
            System.out.println("文件读入异常");
        }
    }
}
  • ProducerController类
点击查看代码
public class ProducerController {
    /**
     * 提示用户生成题目
     * @throws InputMismatchException 输入匹配错误异常
     */
    public void inputProblemSettings () {
        System.out.println("四则运算生成器生成题目\n");
        Scanner scanner = null;
        try {
            scanner = new Scanner(System.in);

            System.out.print("请输入生成题目个数:"); // 输入题目个数
            int numberOfProblems  = scanner.nextInt();
            if (numberOfProblems  <= 0) {
                System.out.println("生成题目个数必须为正整数。\n");
                inputProblemSettings (); // 重新调用以获取有效输入
                return;
            }
            System.out.print("请输入最大自然数:"); // 输入自然数范围
            int maxRange = scanner.nextInt();
            if (maxRange <= 0) {
                System.out.println("最大自然数必须为正整数。\n");
                inputProblemSettings (); // 重新调用以获取有效输入
                return;
            }

            generateArithmeticProblem(numberOfProblems , maxRange); // 生成题目
        } catch (InputMismatchException e) {
            System.out.println("输入数据错误,请输入数字。\n\n\n"); // 输入格式错误提示
            if (scanner != null) {
                scanner.nextLine(); // 清除错误输入
            }
            inputProblemSettings (); // 重新调用以获取有效输入
        } catch (IOException e) {
            System.out.println("文件创建失败"); // 文件创建异常处理
        }
    }

    /**
     * 生成并输出题目到文件
     * @param numberOfProblems 题目个数
     * @param maxRange 最大自然数范围
     * @throws IOException 文件异常
     */
    public void generateArithmeticProblem(int numberOfProblems, int maxRange) throws IOException {
        FileUtil fileUtil = new FileUtil();
        // 创建题目和答案文件
        File exercisesFile = new File("Exercises.txt");
        File answersFile = new File("Answers.txt");

        // 删除已存在的文件
        if (exercisesFile.exists()){
            boolean flag = exercisesFile.delete(); // 删除已有文件
            if (!flag) {
                System.out.println("无法删除旧的题目文件"); // 删除失败时输出提示
            }
        }
        if (answersFile.exists()){
            boolean flag = answersFile.delete(); // 删除已有文件
            if (!flag) {
                System.out.println("无法删除旧的题目文件"); // 删除失败时输出提示
            }
        }

        // 创建新文件
        try (PrintStream exercisesPrintStream = new PrintStream(Files.newOutputStream(exercisesFile.toPath()));
             PrintStream answersPrintStream = new PrintStream(Files.newOutputStream(answersFile.toPath()))) {

            Random random = new Random(); // 随机数生成器
            CreateFraction createFraction = new CreateFraction(); // 分数题目生成器
            CreateInteger createInteger = new CreateInteger(); // 整数题目生成器

            for (int i = 1; i <= numberOfProblems; i++) {
                boolean isFraction = random.nextBoolean(); // 返回true或false
                String[] expressionAndAns;
                if (isFraction) {
                    expressionAndAns = createFraction.createFractionProblem(maxRange); // 生成分数题目
                } else {
                    expressionAndAns = createInteger.createIntegerProblem(maxRange); // 生成整数题目
                }
                fileUtil.outputFile(i, expressionAndAns, exercisesPrintStream, answersPrintStream); // 输出题目和答案
            }
            System.out.println("题目和与之对应的答案文件创建成功。"); // 成功提示
        }
    }
}
  • CreateFraction类
点击查看代码
public class CreateFraction {

    private static final String[] OPERATOR = {"+", "-"}; // 操作符数组

    /**
     * 真分数公式与答案生成器,分为加法与减法
     * @param maxRange 范围,用于生成随机数
     * @return 包含生成的数学表达式和结果的字符串数组
     */
    public String[] createFractionProblem(int maxRange) {
        Math math = new Math(); // 创建数学工具类实例
        Random random = new Random(); // 创建随机数生成器
        int operatorCount = 1 + random.nextInt(3); // 操作符的个数为1到3

        CreateInteger create = new CreateInteger(); // 创建整数生成器实例
        int[] operatorIndex = create.indexOfOperator(operatorCount, 2, random); // 获取操作符的下标

        // 生成第一个操作数
        int[] coprimeNumber1 = math.createCoprimeNumbers(maxRange, random); // 生成互质数
        int x = coprimeNumber1[0]; // 分子
        int y = coprimeNumber1[1]; // 分母

        // 将假分数转化为真分数字符串
        StringBuilder expression = new StringBuilder(math.shamToProperFraction(x, y));

        // 循环生成剩下的操作数
        for (int i = 0; i < operatorCount; i++) {
            // 生成剩下的操作数
            int[] coprimeNumber2 = math.createCoprimeNumbers(maxRange, random); // 生成新的互质数
            int num_x = coprimeNumber2[0]; // 新的分子
            int num_y = coprimeNumber2[1]; // 新的分母

            String currentOperator = OPERATOR[operatorIndex[i]]; // 获取当前操作符

            // 处理加法
            if (currentOperator.equals("+")) {
                // 分母相乘,分子相加
                x = x * num_y + y * num_x;
            }
            else { // 处理减法
                int count = 0; // 用于防止无限循环的计数器
                // 确保差为非负数
                while (x * num_y - y * num_x < 0) {
                    // 重新生成互质数
                    coprimeNumber2 = math.createCoprimeNumbers(maxRange, random);
                    num_x = coprimeNumber2[0]; // 更新新的分子
                    num_y = coprimeNumber2[1]; // 更新新的分母
                    count++;
                    if (count >= 10) { // 防止无限循环
                        num_x = x - 1; // 设置一个默认值
                        num_y = y; // 保持分母不变
                    }
                }
                // 分母相乘,分子相减
                x = x * num_y - y * num_x;
            }
            // 更新分母
            y = y * num_y;

            // 转换当前操作数为真分数字符串并拼接表达式
            String num = math.shamToProperFraction(num_x, num_y);
            expression.append(currentOperator).append(num);
        }

        // 计算最大公因数以简化结果
        int gcd = math.greatFactor_GCD(x, y);
        if (gcd < 0) {
            return createFractionProblem(maxRange); // 返回-1,让生成重新生成
        }
        // 化简结果
        x /= gcd;
        y /= gcd;

        // 将最终结果转化为真分数字符串并拼接等号
        String ans = math.shamToProperFraction(x, y);
        expression.append("=");

        // 返回生成的表达式和结果
        return new String[]{expression.toString(), ans};
    }
}
  • CreateInteger类
点击查看代码
public class CreateInteger {

    private static final String[] OPERATOR = {"+", "-", "*", "÷"}; // 操作符数组

    /**
     * 整数生成器
     * @param range 范围,用于生成随机数
     * @return 包含生成的数学表达式和结果的字符串数组
     */
    public String[] createIntegerProblem(int range) {
        Random random = new Random();
        int operatorCount = 1 + random.nextInt(3); // 随机生成操作符的个数(1到3个)
        int operandCount = operatorCount + 1; // 操作数的数量
        int[] operand = new int[operandCount]; // 存储操作数

        // 获取操作符的下标数组
        int[] operatorIndex = indexOfOperator(operatorCount, 4, random);

        // 随机生成操作数
        for (int i = 0; i < operandCount; i++) {
            operand[i] = random.nextInt(range); // 生成范围内的随机数
        }

        String problem = stitchingProblem(operatorCount, operand, operatorIndex); // 拼接公式

        int ans = calculator(problem); // 使用 calculator方法 计算结果

        // 如果结果有效,则返回公式和结果;否则重新生成问题
        if (ans > 0) {
            return new String[]{problem.toString(), String.valueOf(ans)}; // 返回公式和结果
        } else {
            return createIntegerProblem(range); // 递归调用以重新生成问题
        }

    }

    /**
     * 随机产生操作符的对应的字符数组的下标
     * @param operatorCount 操作符的数量
     * @param operatorTypes 操作符种类数量
     * @param random 随机数生成器
     * @return 随机生成的操作符下标数组
     */
    public int[] indexOfOperator(int operatorCount, int operatorTypes, Random random) {
        int[] operatorIndex = new int[operatorCount]; // 存储操作符下标
        // 随机生成操作符下标
        for (int i = 0; i < operatorCount; i++) {
            operatorIndex[i] = random.nextInt(operatorTypes); // 获取随机下标
        }
        return operatorIndex; // 返回生成的下标数组
    }

    /**
     * 拼接数学表达式
     * @param operatorCount 操作符数量
     * @param operand 操作数数组
     * @param operatorIndex 操作符下标数组
     * @return 拼接后的数学表达式字符串
     */
    public String stitchingProblem(int operatorCount, int[] operand, int[] operatorIndex) {
        int bracketForm = new Random().nextInt(2); // 随机决定是否使用括号
        StringBuilder expression = new StringBuilder(); // 用于拼接公式
        // 根据操作符数量拼接表达式
        switch (operatorCount) {
            case 1:// a+b型
                expression.append(String.format("%s %s %s =", operand[0], OPERATOR[operatorIndex[0]], operand[1]));
                break;
            case 2: {// a+b+c 型
                if (bracketForm == 0) {
                    expression.append(String.format("%s %s %s %s %s =",operand[0],OPERATOR[operatorIndex[0]],
                            operand[1],OPERATOR[operatorIndex[1]],operand[2]));

                } else {//a+(b+c)型
                    expression.append(String.format("%s %s ( %s %s %s ) =",operand[0],OPERATOR[operatorIndex[0]],
                            operand[1],OPERATOR[operatorIndex[1]],operand[2]));
                }
                break;
            }
            case 3: {//a+((b+c)-d)型
                if (bracketForm == 0) {
                    expression.append(String.format("%s %s (( %s %s %s ) %s %s) =",operand[0],OPERATOR[operatorIndex[0]],
                            operand[1],OPERATOR[operatorIndex[1]],operand[2],OPERATOR[operatorIndex[2]],operand[3]));
                }
                else {//(a+b)+(c+d)型
                    expression.append(String.format("( %s %s %s ) %s ( %s %s %s ) =",operand[0],OPERATOR[operatorIndex[0]],
                            operand[1],OPERATOR[operatorIndex[1]],operand[2],OPERATOR[operatorIndex[2]],operand[3]));
                }
                break;
            }//可添加更多类型,如a+b+c+d型,a+(b+c)-d型等等
        }
        return expression.toString(); // 返回拼接的数学表达式
    }

    /**
     * 计算给定表达式的值
     * @param s 输入的数学表达式字符串
     * @return 计算结果,返回整数值
     */
    public int calculator(String s) {
        Stack<Integer> numStack = new Stack<>(); // 用于存放数字的栈
        Stack<String> operatorStack = new Stack<>(); // 用于存放操作符的栈
        HashMap<String, Integer> hashMap = new HashMap<>(); // 存放运算符优先级的哈希表
        hashMap.put("(", 0); // 左括号优先级最低
        hashMap.put("+", 1); // 加法优先级
        hashMap.put("-", 1); // 减法优先级
        hashMap.put("*", 2); // 乘法优先级
        hashMap.put("÷", 2); // 除法优先级

        String formula = s.replaceAll(" ", ""); // 去除输入字符串中的空格

        for (int i = 0; i < formula.length();) {
            StringBuilder digit = new StringBuilder(); // 当前数字的StringBuilder
            char c = formula.charAt(i); // 获取当前字符

            // 处理数字,收集连续的数字字符
            while (Character.isDigit(c)) { // 判断当前字符是否为数字
                digit.append(c); // 将数字字符加入digit
                i++;
                if (i < formula.length()) {
                    c = formula.charAt(i); // 获取下一个字符
                } else {
                    break; // 结束循环
                }
            }

            // 处理操作符
            if (digit.length() == 0) { // 如果没有数字,说明当前是操作符
                switch (c) {
                    case '(': {
                        operatorStack.push(String.valueOf(c)); // 压入左括号
                        break;
                    }
                    case ')': { // 处理右括号
                        String stmp = operatorStack.pop(); // 弹出操作符栈顶元素
                        while (!operatorStack.isEmpty() && !stmp.equals("(")) { // 计算直到遇到左括号
                            int a = numStack.pop(); // 弹出操作数a
                            int b = numStack.pop(); // 弹出操作数b
                            int result = performSingleOperation(b, a, stmp); // 进行计算
                            if (result < 0) return -1; // 错误处理
                            numStack.push(result); // 将结果压入数字栈
                            stmp = operatorStack.pop(); // 更新操作符
                        }
                        break;
                    }
                    case '=': { // 处理等号
                        String stmp;
                        while (!operatorStack.isEmpty()) { // 计算所有剩余操作符
                            stmp = operatorStack.pop(); // 弹出操作符
                            int a = numStack.pop(); // 弹出操作数a
                            int b = numStack.pop(); // 弹出操作数b
                            int result = performSingleOperation(b, a, stmp); // 进行计算
                            if (result < 0) return -1; // 错误处理
                            numStack.push(result); // 将结果压入数字栈
                        }
                        break;
                    }
                    default: { // 处理其他操作符
                        String stmp;
                        while (!operatorStack.isEmpty()) { // 当符号栈非空时
                            stmp = operatorStack.pop(); // 获取栈顶操作符
                            // 比较优先级
                            if (hashMap.get(stmp) >= hashMap.get(String.valueOf(c))) {
                                int a = numStack.pop(); // 弹出操作数a
                                int b = numStack.pop(); // 弹出操作数b
                                int result = performSingleOperation(b, a, stmp); // 进行计算
                                if (result < 0) return -1; // 错误处理
                                numStack.push(result); // 将结果压入数字栈
                            } else {
                                operatorStack.push(stmp); // 优先级高的操作符回压
                                break; // 退出循环
                            }
                        }
                        operatorStack.push(String.valueOf(c)); // 压入当前操作符
                        break;
                    }
                }
            } else { // 处理数字
                numStack.push(Integer.valueOf(digit.toString())); // 将数字压入数字栈
                continue; // 结束本次循环,回到for语句进行下一次循环
            }
            i++; // 移动到下一个字符
        }
        return numStack.peek(); // 返回栈顶的数字,即表达式的计算结果
    }


    /**
     * 执行单个操作的计算
     * @param a 操作数1
     * @param b 操作数2
     * @param operator 操作符
     * @return 计算结果
     */
    public int performSingleOperation(int a, int b, String operator) {
        switch (operator) {
            case "+":
                return a + b; // 加法
            case "-":
                return a - b; // 减法
            case "*":
                return a * b; // 乘法
            case "÷":
                if (b == 0) return -1; // 除数为零时返回错误
                return a / b; // 除法
            default:
                return -1; // 返回错误
        }
    }
}
  • FileUtil类
点击查看代码
public class FileUtil {
    // 读取题目文件
    public List<String> readExerciseFile(String path) throws IOException {
        BufferedReader exerciseReader = new BufferedReader(new FileReader(path));
        String exercise;
        List<String> exercises = new ArrayList<>();

        // 按行读取文件内容
        while ((exercise = exerciseReader.readLine()) != null) {
            String[] split = exercise.split("=");
            //String[] split = exercise.split("[=.]");
            if (split.length >= 2) {
                exercises.add(split[1].trim()); // 提取并去除空白
                //System.out.println(split[1].trim());
            } else {
                exercises.add(" "); // 如果格式不对,添加空格
                System.out.println(split[0]+"答案未输入或写入文件的题目格式错误。");
            }
        }
        return exercises; // 返回题目列表
    }

    // 读取答案文件
    public List<String> readAnswerFile(String path) throws IOException {
        BufferedReader answerReader = new BufferedReader(new FileReader(path));
        String answer;
        List<String> answers = new ArrayList<>();

        // 按行读取文件内容
        while ((answer = answerReader.readLine()) != null) {
            String[] split = answer.split(" ");
            if (split.length >= 2) {
                answers.add(split[1].trim()); // 提取并去除空白
                //System.out.println(split[1].trim());
                //trim() 方法用于去掉字符串两端的空格
            } else {
                answers.add(" "); // 如果格式不对,添加空格
                System.out.println(split[0]+"写入文件的答案格式错误。");
            }
        }
        return answers; // 返回答案列表
    }

    // 写入成绩文件
    public void writeGradeFile(List<String> correct, List<String> wrong) throws IOException {
        File grade = new File("Grade.txt");
        if (grade.exists()) {
            boolean flag = grade.delete(); // 删除已有文件
            if (!flag) {
                System.out.println("无法删除成绩文件"); // 删除失败时输出提示
            }
        }

        if (grade.createNewFile()) {
            try (FileOutputStream gradeOutput = new FileOutputStream(grade);
                 PrintStream gradePrintStream = new PrintStream(gradeOutput)) {
                // 写入正确题号
                String corrects = String.join(",", correct);
                gradePrintStream.println("Correct:" + correct.size() + " (" + corrects + ")");
                // 写入错误题号
                String wrongs = String.join(",", wrong);
                gradePrintStream.println("Wrong:" + wrong.size() + " (" + wrongs + ")");
            }
        }
    }
    /**
     * 输出题目和答案到指定的PrintStream。
     *
     * @param index   题目编号
     * @param problem 题目和答案数组
     * @param streams 可变参数,用于传入输出流
     */
    public void outputFile(int index, String[] problem, PrintStream... streams) {
        // 确保至少有两个输出流
        if (streams.length != 2) {
            System.out.println("必须提供两个输出流:一个用于题目,一个用于答案。");
            return;
        }
        try {
            // 输出题目到第一个PrintStream
            streams[0].println(index + ". " + problem[0]); // 输出题目
            // 输出答案到第二个PrintStream
            streams[1].println(index + ". " + problem[1]); // 输出答案
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界。"); // 数组越界异常处理
        }
    }
}
  • MathUtil类
点击查看代码
public class MathUtil {
    /**
     * 用辗转相除法求最大公因数
     * @param x 第一个数
     * @param y 第二个数
     * @return 最大公因数
     */
    public int greatFactor_GCD(int x, int y) {
        if (x == 0||y == 0)
            return -1;//返回-1,让生成重新生成
        while (y != 0) {
            int temp = y;
            y = x % y;
            x = temp;
        }
        return x; // 当y为0时,x就是最大公因数
    }

    /**
     * 生成一对互质数
     * @param range 随机数范围
     * @param random 随机数生成器
     * @return 互质数数组
     */
    public int[] createCoprimeNumbers(int range, Random random) {
        int x, y;
        // 循环直到找到一对互质数
        do {
            x = 1 + random.nextInt(range); // 生成随机数 x
            y = 1 + random.nextInt(range); // 生成随机数 y
        } while (greatFactor_GCD(x, y) != 1); // 检查 x 和 y 是否互质
        return new int[]{x, y}; // 返回互质数对
    }


    /**
     * 将假分数转换为真分数
     * @param x 分子
     * @param y 分母
     * @return 真分数字符串
     */
    public String shamToProperFraction(int x, int y) {
        // 判断是否为假分数
        if (x > y) {
            int n = x / y; // 计算整数部分
            x = x % y; // 计算新的分子

            // 如果分子为0,返回整数部分
            if (x == 0) {
                return String.valueOf(n);
            }
            // 返回带分数形式,例如 "1'2/3"
            return n + "'" + x + "/" + y;
        }
        // 如果分子和分母相等,返回1
        else if (x == y) {
            return "1";
        }
        // 如果分母为1,返回分子
        else if (y == 1) {
            return String.valueOf(x);
        }
        // 如果分子为0,返回0
        else if (x == 0) {
            return "0";
        }

        // 返回正常分数形式,例如 "2/3"
        return x + "/" + y;
    }
}

5性能分析

本次的性能分析以生成10000道且操作数范围为10以内的四则运算题目为例

5.1生成的题目与答案

5.2内存消耗

总内存消耗为 304,601 kB,内存方面消耗较高。内存占用主要集中在 String、StringBuilder 和 HashMap,后续可以通过优化这些部分代码来降低应用的内存消耗。

5.3CPU负载

CPU负载最高只在5%左右

5.4性能优化分析

  1. 字符串使用:

由于 String 和 StringBuilder 的占用较高,代码中有不必要的字符串拼接或频繁创建对象的地方。可以用StringBuilder 来代替字符串拼接。

  1. HashMap 使用:

HashMap 实例使用过多,可以尝试利用其他数据结构,或是合理调整 HashMap 的初始容量以及负载因子,以减少内存占用。

  1. 对象复用:

通过对象池或复用模式来降低对象的创建和销毁所带来的内存占用。减少不必要的对象实例:另外减少不必要的临时对象创建,如使用局部变量而不是全局变量。

6单元测试

覆盖率

测试结果

测试代码链接

-测试代码-

7项目小结

在这次编程作业中,我和柯锦宏同学一起讨论,他主要负责编写代码,后期的测试和报告则由我负责,在这一次的作业中,我也从伙伴身上学习到了很多,认识到自己与他人之间的差距,他在编程过程中也耐心的解答我的疑惑,在这个过程中不断的完善代码。两个人一起处理问题,互相汲取对方好的想法,有些细节没有考虑到的,另一个人可以帮忙补充,这样使得效率也大大提高。例如在我们进行最后测试的过程中,我发现当计算答案时如果答案为空则会出错,在这个情况下我们进行讨论之后也克服了这个问题。

posted on 2024-09-28 10:43  啥也不会的c  阅读(26)  评论(0编辑  收藏  举报