四则运算

发布时间 2023-09-28 15:23:30作者: 曾中港
软件工程 计科21级四班
作业地址 https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13016
作业目标 结对项目

GitHub地址

https://github.com/2077435277/FourOperation

成员信息

姓名 学号
冯威炀 3121005123
曾中港 3121005151

PSP表格

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

项目结构

文件目录如下:

代码展示

` 生成算数表达式的代码如下:

/**
 * 生成n个随机表达式
 */
public static List<String> generalExpressions(Integer maxNumber, Integer exNumber) {
    List<String> expressions = new ArrayList<>();
    //导入random包
    Random random = new Random();
    int number = 0;
    //进入循环
    while (number < exNumber) {
        StringBuilder expression = new StringBuilder();
        //定义四个变量,分别表示分子和分母
        int numerator1,numerator2,denominator1,denominator2;
        //判断生成的是分数还是整数
        if(random.nextInt(2)==1){
            numerator1 = random.nextInt(maxNumber);
            denominator1 = numerator1 + random.nextInt(maxNumber-numerator1);
            if(denominator1==0){
                denominator1++;
            }
            expression.append(numerator1).append("/").append(denominator1);
        }else{
            //此时生成的是整数
            numerator1 = random.nextInt(maxNumber);
            denominator1 = -1;
            expression.append(numerator1);
        }
        char operation;
        //进入循环,生成最多三个运算符的表达式
        //先随机生成最多的运算符数量
        int operationNumber = random.nextInt(OPERATION_NUMBER) + 1;
        for (int i = 0; i < operationNumber; i++) {
            //运用随机数生成运算符号
            operation = operations[random.nextInt(4)];
            switch (operation) {
                //因为减法运算时不能让前面的数小于后面的数,因此num2的随机生成要在具体的分支中生成
                case '+' -> {
                    if(random.nextInt(2)==1){
                        numerator2 = random.nextInt(maxNumber);
                        denominator2 = numerator2 + random.nextInt(maxNumber-numerator2);
                        if(denominator2==0){
                            denominator2++;
                        }
                        expression.append(" + ").append(numerator2).append("/").append(denominator2);
                        numerator1 = numerator2;
                        denominator1 = denominator2;
                    }else{
                        numerator2 = random.nextInt(maxNumber);
                        expression.append(" + ").append(numerator2);
                        numerator1 = numerator2;
                        denominator1 = -1;
                    }
                }
                case '-' -> {
                    //判断生成整数还是分数
                    if(random.nextInt(2)==1){
                        if(numerator1==0){
                            expression.append(" - ").append(0);
                        }else{
                            numerator2 = random.nextInt(numerator1);
                            expression.append(" - ").append(numerator2);
                        }
                        denominator1 = -1;
                    }else{
                        //如果前一位不是分数则随便生成
                        if(denominator1==-1){
                            numerator2 = random.nextInt(maxNumber);
                            denominator2 = numerator2 + random.nextInt(maxNumber-numerator2);
                            if(denominator2==0){
                                denominator2++;
                            }
                            expression.append(" - ").append(numerator2).append("/").append(denominator2);
                        }else{
                            //如果前面一位是分数要保证前面的分数更大
                            if(numerator1==1 && denominator1 == 9){
                                expression.append(" - ").append(0);
                                denominator1 = -1;
                            }else{
                                numerator2 = random.nextInt(maxNumber);
                                denominator2 = numerator2 + random.nextInt(maxNumber-numerator2);
                                while(!determineLegal(numerator1,denominator1,numerator2,denominator2)){
                                    numerator2 = random.nextInt(maxNumber);
                                    denominator2 = numerator2 + random.nextInt(maxNumber-numerator2);
                                }
                                expression.append(" - ").append(numerator2).append("/").append(denominator2);
                                denominator1 = denominator2;
                                numerator1 = numerator2;
                            }
                        }
                    }
                }
                case '*' -> {
                    if(random.nextInt(2)==1){
                        numerator2 = random.nextInt(maxNumber);
                        denominator2 = numerator2 + random.nextInt(maxNumber-numerator2);
                        if(denominator2==0){
                            denominator2++;
                        }
                        expression.append(" * ").append(numerator2).append("/").append(denominator2);
                        numerator1 = numerator2;
                        denominator1 = denominator2;
                    }else{
                        numerator2 = random.nextInt(maxNumber);
                        expression.append(" * ").append(numerator2);
                        numerator1 = numerator2;
                        denominator1 = -1;
                    }
                }
                case '/' -> {
                    if(random.nextInt(2)==1){
                        numerator2 = random.nextInt(maxNumber);
                        denominator2 = numerator2 + random.nextInt(maxNumber-numerator2);
                        if(denominator2==0){
                            denominator2++;
                        }
                        expression.append(" / ").append(numerator2).append("/").append(denominator2);
                        numerator1 = numerator2;
                        denominator1 = denominator2;
                    }else{
                        numerator2 = random.nextInt(maxNumber);
                        expression.append(" / ").append(numerator2);
                        numerator1 = numerator2;
                        denominator1 = -1;
                    }
                }
            }
        }
        //将字符串存入集合中
        expressions.add(expression.toString());
        number++;
    }
    return expressions;
}

/**
 * 判断分数是否合法
 * @param numerator1 分子1
 * @param denominator1 分母1
 * @param numerator2 分子2
 * @param denominator2 分母2
 * @return 返回是否合法
 */
public static boolean determineLegal(int numerator1,int denominator1,int numerator2,int denominator2){
    return numerator1*denominator2<numerator2*denominator1;
}

分母进行相加减:
/** * 分子 */ private int numerator; /** * 分母 */ private int denominator;

public int getNumerator() {
    return numerator;
}

public void setNumerator(int numerator) {
    this.numerator = numerator;
}

public int getDenominator() {
    return denominator;
}

public void setDenominator(int denominator) {
    this.denominator = denominator;
}

public Fraction(int numerator, int denominator) {
    this.numerator = numerator;
    this.denominator = denominator;
}

// 简化分数
private static Fraction simplify(int numerator, int denominator) {
    int gcd = gcd(numerator, denominator);
    return new Fraction(numerator / gcd, denominator / gcd);
}

// 计算最大公约数
private static int gcd(int a, int b) {
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

// 计算两个分数的加法
public static Fraction add(Fraction a, Fraction b) {
    int newNumerator = a.numerator * b.denominator + b.numerator * a.denominator;
    int newDenominator = a.denominator * b.denominator;
    return simplify(newNumerator, newDenominator);
}

// 计算两个分数的除法
public static Fraction divide(Fraction a, Fraction b) {
    int newNumerator = a.numerator * b.denominator;
    int newDenominator = a.denominator * b.numerator;
    return simplify(newNumerator, newDenominator);
}

// 计算两个分数的乘法
public static Fraction multiply(Fraction a, Fraction b) {
    int newNumerator = a.numerator * b.numerator;
    int newDenominator = a.denominator * b.denominator;
    return simplify(newNumerator, newDenominator);
}

// 计算两个分数的减法
public static Fraction subtract(Fraction a, Fraction b) {
    int newNumerator = a.numerator * b.denominator - b.numerator * a.denominator;
    int newDenominator = a.denominator * b.denominator;
    return simplify(newNumerator, newDenominator);
}

// 将分数转换为字符串表示
@Override
public String toString() {
    if (denominator == 1) {
        return numerator + "";
    }
    if (numerator > denominator) {
        int sum = numerator / denominator;
        int nowNum = numerator % denominator;
        return sum + "`" + nowNum + "/" + denominator;
    }
    //转成真分数
    return numerator + "/" + denominator;
}`

IO文件操作:
public static void writeFile(List<String> expressions,String filePath){ try { // 创建文件对象 File file = new File(filePath); // 如果文件不存在,则创建文件 if (!file.exists()) { file.createNewFile(); } // 创建文件写入流 FileWriter fileWriter = new FileWriter(file); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); // 将集合数据写入文件 for (String item : expressions) { bufferedWriter.write(item); bufferedWriter.newLine(); // 换行 } // 关闭文件写入流 bufferedWriter.close(); System.out.println("集合数据已写入文件 " + filePath); } catch (IOException e) { e.printStackTrace(); } }

/**
 * 读出文件
 */
public static List<String> readFile(String filePath){
    // 创建集合用于存储读取的数据
    List<String> collectionData = new ArrayList<>();
    try {
        // 创建文件读取流
        FileReader fileReader = new FileReader(filePath);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String line;
        // 逐行读取文件内容
        while ((line = bufferedReader.readLine()) != null) {
            collectionData.add(line);
        }
        // 关闭文件读取流
        bufferedReader.close();
        // 打印读取的数据
        for (String item : collectionData) {
            System.out.println(item);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return  collectionData;
}`

项目演示:

生成十道算数表达式:

生成一万道算数表达式:

输出到文件中:

与答案进行比较:

性能分析:

总结:

1.项目从0到1打磨需要耐心与毅力,需要不断的摸索和学习
2.遇到困难的解决方式不仅仅只是上网搜索资料,更多的是了解代码底层的实现与用法