作业3:四则运算

这个作业属于哪个课程 软件工程
这个作业要求在哪里 四则运算
这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序

一、成员个人信息

姓名 学号
蔡梓严 3122004686
巫育平 3122004708

Github地址:https://github.com/baibansunben/Four-operations

二、PSP表格

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

三、效能分析

  • 测试生成题目

  • CPU负载

  • 性能优化
    1.减少过程调用
    2.减少内存引用和访问

四、实现过程

  • 需求分析

  • 项目结构

五、代码说明

  • main

public class MathExercise {
    public static void main(String[] args) {
        // 解析命令行参数
        System.out.println("Usage: java MathExercise [-n numQuestions] [-r range]");
        Scanner input=new Scanner(System.in);
        System.out.println("请输入生成题目的数量:");
        int numQuestions = input.nextInt();
        Scanner input2=new Scanner(System.in);
        System.out.println("请输入题目中数值的范围:");
        int range = input.nextInt();
//        int numQuestions = 10;
//        int range = 10;
        boolean generateExercises = true;
        boolean gradeExercises = false;
        String exerciseFile ="exercises.txt";;
        String answerFile = "answers.txt";
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "-n":
                    numQuestions = Integer.parseInt(args[++i]);
                    break;
                case "-r":
                    range = Integer.parseInt(args[++i]);
                    break;
                case "-e":
                    exerciseFile = args[++i];
                    generateExercises = false;
                    break;
                case "-a":
                    answerFile = args[++i];
                    gradeExercises = true;
                    break;
            }
        }

        // 生成题目和答案
        List<String> exercises = new ArrayList<>();
        List<String> answers = new ArrayList<>();
        if (generateExercises) {
            Random random = new Random();

            for (int i = 0; i < numQuestions; i++) {
                String exercise = generateExercise(random, range);
                String answer = evaluateExpression(exercise);

                exercises.add(exercise);
                answers.add(answer);
            }
        }

        // 打印题目和答案
        for (int i = 0; i < numQuestions; i++) {
            System.out.println("Exercise " + (i + 1) + ": " + exercises.get(i));
            System.out.println("Answer " + (i + 1) + ": " + answers.get(i));
        }

        // 写入题目和答案到文件
        if (generateExercises) {
            try {
                FileWriter exerciseWriter = new FileWriter("Exercises.txt");
                FileWriter answerWriter = new FileWriter("Answers.txt");

                for (String exercise : exercises) {
                    exerciseWriter.write(exercise + "\n");
                }

                for (String answer : answers) {
                    answerWriter.write(answer + "\n");
                }

                exerciseWriter.close();
                answerWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (true) {

            if (exerciseFile == null || answerFile == null) {
                System.out.println("Exercise file or answer file not specified.");
                return;
            }

            try {

                Scanner exerciseScanner = new Scanner(new File(exerciseFile));
                Scanner answerScanner = new Scanner(new File(answerFile));

                List<String> correctAnswers = new ArrayList<>();
                List<String> wrongAnswers = new ArrayList<>();

                int questionNumber = 1;
                while (exerciseScanner.hasNextLine() && answerScanner.hasNextLine()) {
                    String exercise = exerciseScanner.nextLine();
                    String answer = answerScanner.nextLine();

                    String userAnswer = evaluateExpression(exercise);
                    if (userAnswer.equals(answer)) {
                        correctAnswers.add(String.valueOf(questionNumber));
                    } else {
                        wrongAnswers.add(String.valueOf(questionNumber));
                    }

                    questionNumber++;
                }

                FileWriter gradeWriter = new FileWriter("Grade.txt");

                gradeWriter.write("Correct: " + correctAnswers.size() + " (" + String.join(", ", correctAnswers) + ")\n");
                gradeWriter.write("Wrong: " + wrongAnswers.size() + " (" + String.join(", ", wrongAnswers) + ")\n");
                gradeWriter.close();
                System.out.println("Grade file created successfully.");

            } catch (IOException e) {
                e.printStackTrace();
            }
        }}

  • 生成四则运算题目

    public static String generateExercise(Random random, int range) {
        int a = random.nextInt(range) + 1;
        int b = random.nextInt(range) + 1;
        int operator = random.nextInt(4);

        String exercise;
        switch (operator) {
            case 0:
                exercise = a + " + " + b;
                break;
            case 1:
                exercise = a + " - " + b;
                break;
            case 2:
                exercise = a + " * " + b;
                break;
            case 3:
                exercise = a + " / " + b;
                break;
            default:
                exercise = "";
        }

        return exercise;
    }

  • 计算四则运算表达式的结果

public static String evaluateExpression(String expression) {
        Stack<Integer> operandStack = new Stack<>();
        Stack<Character> operatorStack = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char ch = expression.charAt(i);

            if (ch == ' ')
                continue;

            if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
                while (!operatorStack.isEmpty() && precedence(operatorStack.peek()) >= precedence(ch)) {
                    processAnOperator(operandStack, operatorStack);
                }

                operatorStack.push(ch);
            } else if (ch >= '0' && ch <= '9') {
                StringBuilder operand = new StringBuilder();
                while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                    operand.append(expression.charAt(i++));
                }
                i--;

                operandStack.push(Integer.parseInt(operand.toString()));
            }
        }

        while (!operatorStack.isEmpty()) {
            processAnOperator(operandStack, operatorStack);
        }

        return operandStack.pop().toString();
    }

  • 处理运算符

public static void processAnOperator(Stack<Integer> operandStack, Stack<Character> operatorStack) {
        char operator = operatorStack.pop();
        int operand1 = operandStack.pop();
        int operand2 = operandStack.pop();

        switch (operator) {
            case '+':
                operandStack.push(operand2 + operand1);
                break;
            case '-':
                operandStack.push(operand2 - operand1);
                break;
            case '*':
                operandStack.push(operand2 * operand1);
                break;
            case '/':
                operandStack.push(operand2 / operand1);
                break;
        }
    }

  • 运算符优先级

  public static int precedence(char operator) {
        if (operator == '+' || operator == '-')
            return 1;
        else if (operator == '*' || operator == '/')
            return 2;
        else
            return 0;
    }}

六、测试运行

  • 测试生成习题

  • 测试答案

  • 统计得分情况

  • 统计对错情况

以上通过1w道题目的结果验证程序的正确性

七、项目小结

  • 结对编程:
    通过结对编程,两个人可以充分发挥各自的优点,共同进步,实现"1+1>2"的效果。
    我负责测试及博客的编写,队友负责写算法及性能分析。
  • 编程模式:
    采用一个人编程,一个人监督并帮忙的模式。
    定期角色互换,思维互换,避免思维僵硬,学习对方的优点,解决不专注问题。
  • 困难处理:
    如果一位成员感觉思路不通或无法进行下去,另一人应积极沟通并提供帮助。
    初始阶段可能存在代码思路分歧,但随后的沟通、借鉴经验和共同解决问题将提高开发效率。
  • 收获与提升:
    结对编程不仅提高编程能力,还促进团队协作、沟通和表达能力的发展。
posted @ 2024-03-25 21:01  Shangrila  阅读(18)  评论(0编辑  收藏  举报