首页 > 其他分享 >结对项目

结对项目

时间:2024-09-27 19:45:46浏览次数:1  
标签:结对 项目 int denominator numerator num Fraction new

一、作业信息

这个作业属于哪个课程 班级链接
这个作业要求在哪里 作业要求
这个作业的目标 组队设计实现一个生成小学四则运算题目的命令行程序

二、小组成员

姓名 学号 github
陈大锴 3122004816 https://github.com/ez4-cdk/ez4-cdk/tree/master/3122004816/algorithm
陈祖民 3122004822 https://github.com/MIR-mIsTEo/3122004822-02

三、PSP表格

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

四、设计实现过程

1、项目结构

2、接口设计与实现

①.Expression

此类为表达式的对象,成员为String类型的expression、构造方法Expression(String)、getter以及核心方法evaluate():String

②Fratcion

此类为分数的对象,对于分数的存储,选用"A'B/C"的带分数形式存储
加减乘除的思路为:
加法:分母分子同分,分子相加,分母取最小公倍数,返回的新分数再化简
减法:分母分子同分,分子相加,分母取最小公倍数,返回的新分数再化简
乘法:分子乘分子,分母乘分母
乘法:分子分母交叉相乘
成员主要有:
int 类型的num————整数部分
int 类型的numerator————分子部分
int 类型的denominator————分母部分
上面三个属性的getter,本分数的构造方法Fraction(Int,Int)
simplify() [将构造的分数化为带分数并且约分]
generateABiggerFraction():Fration [生成一个比本分数更大的分数]
add(Fratcion):Fraction [加]
subtract(Fratcion):Fraction [减]
multiply(Fratcion):Fraction [乘]
divide(Fratcion):Fraction [除]
fromString(String):Fraction [将表达式转化为分数]
gcd(int,int):int [求最大公约数]
toString():String [重写的tostring()方法]

③ExpressionEvaluator

此类为表达式计算器,用于计算表达式的值,先计算括号内的,再计算乘除,最后计算加减
evaluate(String):Fraction 计算一个表达式并返回一个分数
calculate(String):String 识别括号并进入括号内计算的过程
evaluateExpression(String):Fraction 计算的主体过程,包括加减乘除

④FileIO

此类为文件输入输出的工具类
readFile(String):String [读入]
writeOutput(String,Object):String [写出]

⑤Generator

此类为生成器工具类,用户生成各种需要的数据,属于关键类,轴心流程图如下:

       开始
         |
         v
  generateExpressions(num, area) —— > 生成表达式集合的核心函数,num为表达式数量,area为表达式各个参数的取值范围
         |
         v
   循环 i 从 0 到 num-1  —— > 生成每一条表达式
         |  
         v
     generateOperators()  —— > 生成表达式的操作符
         |
         v
   generateNumber(operators.size() + 1, area, operators)  —— > 生成表达式的操作数
         |
         v
    generateExpression(operators, numbers)  —— > 表达式的操作符与操作数按照需求组合
         |
         v
 添加表达式到 expressions 列表
         |
         v
        结束循环
         |
         v
    返回 expressions 列表
         |
         v
        结束

Random 类型的random————随机种子
generateNumber(int,int,List):List [随机生成分数]
generateOperators():List [生成操作符]
sort(List):void [排序]
generateExpressions(int,int):List [生成表达式集合,主要生成函数]
generateBracket(int):List [随机生成括号]
generateExpression(List,List):String [生成每一条字符串类型的表达式]
getOperatorSymbol(int):String [将加减乘除符号解析]

⑥SplashClass

此类为入口类,入口有两个,一个是生成题目与答案的入口,一个是检查答案与表达式答案的入口
main(String[]):void [main函数]
generateExercises(Integer,Integer):void [生成题目的入口]
checkAnswer(String,String):void [检查答案的入口]

五、代码说明

Generator
生成器的类是本程序的核心,负责控制生成操作符、操作数、表达式、表达式集合,层层递进

package com.softwareClass.util;

import com.softwareClass.entity.Expression;
import com.softwareClass.entity.Fraction;

import java.util.*;

public class Generator {
    
    public List generateOperators(){
        int randomArea = 3;
        List list = new ArrayList<>();
        int operatorsCount = random.nextInt(3)+1;
        for(int i=0; i<operatorscount; i++){="" list.add(random.nextint(randomarea));="" if="" (list.contains(3)){="" randomarea="2;" }="" return="" list;="" **="" *="" 参数="" 0="" 加="" 1="" 减="" 2="" 乘="" 3="" 除="" a'b="" c="" 真分数格式="" 随机种子="" private="" static="" final="" random="" random();="" 生成操作数="" public="" list<fraction=""> generateNumber(int count, int area, List operators) {
        List numbers = new ArrayList<>();
        try {
            
            //循环生成数量为count的分数集合
            while (numbers.size() < count) {
                int denominator = random.nextInt(area-3) + 3;
                int numerator = random.nextInt((area - 1) * denominator) + 1;
                Fraction fraction = new Fraction(numerator, denominator);
                numbers.add(fraction);
            }
            
            //排序
            sort(numbers);
            
            //对于除法,选择生成一个比前一个更大的分数
            for (int i = 0; i < operators.size(); i++) {
                if (operators.get(i) == 3) {
                    numbers.set(i+1,numbers.get(i).generateABiggerFraction());
                }
            }
            
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("随机种子初始化失败,请重试.");
        }
        return numbers;
    }

    //排序(降序)
    private void sort(List numbers) {
        numbers.sort((f1, f2) -> {
            int value1 = f1.getNum();
            int value2 = f2.getNum();
            return Integer.compare(value2, value1);
        });
    }

    //主生成函数——生成表达式集合
    public List generateExpressions(int num,int area) {
        List expressions = new ArrayList<>();
        while (expressions.size() < num){
            List operators = generateOperators();
            List numbers = generateNumber(operators.size()+1, area,operators);
            Expression e = new Expression(generateExpression(operators,numbers));
            if (Fraction.fromString(e.evaluate()).getNum()>=0){
                expressions.add(e);
            }
        }
        return expressions;
    }

    //生成括号——在特定索引下生成括号,如果索引合法,则返回索引集合,非法则不生成括号
    public List generateBracket(int num){
        List brackets = new ArrayList<>();
        int leftBracket = random.nextInt(num);
        int rightBracket = random.nextInt(num);
        if (leftBracket<rightbracket&&rightbracket<num){ brackets.add(leftbracket);="" brackets.add(rightbracket);="" return="" brackets;="" }else{="" null;="" }="" 用操作数set和操作符list进行构造表达式="" public="" string="" generateexpression(list<integer=""> operators, List numbers) {
        List numberList = new ArrayList<>(numbers);
        List brackets = generateBracket(numberList.size());
        StringBuilder expressionBuilder = new StringBuilder();
        //类似于e=()这种情况就不用加括号,比如e=(1+2/3)
        if (brackets!=null&&brackets.get(0)==0&&brackets.get(1)==numberList.size()-1){
            brackets = null;
        }
        //每次加入一个分数和一个符号
        for (int i = 0; i < operators.size(); i++) {
            //左括号索引
            if (brackets!=null&&brackets.get(0)==i){
                expressionBuilder.append("(");
            }
            //右括号索引
            expressionBuilder.append(numberList.get(i));
            if (brackets!=null&&brackets.get(1)==i){
                expressionBuilder.append(")");
            }
            expressionBuilder.append(getOperatorSymbol(operators.get(i)));
        }
        //添加最后一个分数
        expressionBuilder.append(numberList.getLast());
        
        //如果右括号没合上,则合上
        if (brackets!=null&&(brackets.get(1)+1)==numberList.size()){
            expressionBuilder.append(")");
        }
        return expressionBuilder.toString();
    }

    // 辅助方法,用于根据操作符的整数值返回相应的符号
    public String getOperatorSymbol(int operator) {
        return switch (operator) {
            case 0 -> " + ";
            case 1 -> " - ";
            case 2 -> " * ";
            case 3 -> " / ";
            default -> throw new IllegalArgumentException("Invalid operator");
        };
    }

}

Fraction
分数的类,至关重要,对每个分数的加减乘除和解析负责

package com.softwareClass.entity;

public class Fraction {
    private int num; // 整数部分
    private int numerator;   // 分子
    private int denominator; // 分母
    
    //三个属性的getter
    public int getNum() {
        return num;
    }

    public int getNumerator() {
        return numerator;
    }

    public int getDenominator() {
        return denominator;
    }

    //构造函数
    public Fraction(int numerator, int denominator) {
        if (denominator == 0) throw new IllegalArgumentException("分母不能为零");
        this.numerator = numerator;
        this.denominator = denominator;
        simplify(); // 在构造时简化分数
    }

    //生成一个比本分数还大的分数
    public Fraction generateABiggerFraction(){
        if (this.num==0&&this.numerator==0)return new Fraction(1,1);
        int thisNumerator = this.num*this.denominator+this.numerator;
        int thisDenominator = this.denominator;
        if (thisDenominator/2 == 0){
            thisDenominator=3;
        }else {
            thisDenominator=thisDenominator/2;
        }
        return new Fraction(thisNumerator,thisDenominator);
    }

    //从字符串解析出分数
    public static Fraction fromString(String str) {
        int denominator,numerator,num;
        String[] temp1,temp2;
        if (str.contains("/")){
            if (str.contains("'")){
                temp1 = str.split("'");
                num = Integer.parseInt(temp1[0]);
                temp2 = temp1[1].split("/");
                denominator = Integer.parseInt(temp2[1]);
                numerator = Integer.parseInt(temp2[0]);
                return new Fraction(num*denominator+numerator,denominator);
            }else{
                temp1 = str.split("/");
                denominator = Integer.parseInt(temp1[1]);
                numerator = Integer.parseInt(temp1[0]);
                return new Fraction(numerator,denominator);
            }
        }else{
            return new Fraction(Integer.parseInt(str),1);
        }
    }

    //加法,分母相乘,分子交叉乘分母并相加
    public Fraction add(Fraction other) {
        int commonDenominator = this.denominator * other.denominator;
        int newNumerator = (this.numerator + this.num * this.denominator) * other.denominator +
                (other.numerator + other.num * other.denominator) * this.denominator;
        return new Fraction(newNumerator, commonDenominator);
    }

    //减法,分母相乘,分子交叉乘分母并相减
    public Fraction subtract(Fraction other) {
        int commonDenominator = this.denominator * other.denominator;
        int newNumerator = (this.numerator + this.num * this.denominator) * other.denominator -
                (other.numerator + other.num * other.denominator) * this.denominator;
        return new Fraction(newNumerator, commonDenominator);
    }

    //乘法,分子分母对应相乘
    public Fraction multiply(Fraction other) {
        int newNumerator = (this.numerator + this.num * this.denominator) * (other.numerator + other.num * other.denominator);
        int newDenominator = this.denominator * other.denominator;
        return new Fraction(newNumerator, newDenominator);
    }
    
    //除法,分子分母交叉相乘
    public Fraction divide(Fraction other) {
        if (other.numerator == 0 && other.num == 0) throw new IllegalArgumentException("不能除以零");
        int newNumerator = (this.numerator + this.num * this.denominator) * other.denominator;
        int newDenominator = this.denominator * (other.numerator + other.num * other.denominator);
        return new Fraction(newNumerator, newDenominator);
    }

    //化简分数
    private void simplify() {
        int gcd = gcd(Math.abs(numerator), Math.abs(denominator)); // 计算最大公约数

        // 更新整数部分与分子、分母
        this.num = this.numerator/this.denominator;
        this.numerator = this.numerator % this.denominator;
        this.numerator /= gcd;
        this.denominator /= gcd;

        // 确保分母为正
        if (denominator < 0) {
            numerator = -numerator;
            denominator = -denominator;
        }
    }

    //求最大公约数
    private int gcd(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return Math.abs(a); // 返回绝对值以确保结果为正
    }

    @Override
    public String toString() {
        if (num == 0) {
            if (numerator == 0) {
                return "0"; // 处理0的情况
            } else {
                return numerator + "/" + denominator; // 只返回分数
            }
        } else {
            if (numerator == 0) {
                return String.valueOf(num); // 只返回整数部分
            }
            return num + "'" + numerator + "/" + denominator; // 返回带分数
        }
    }
}

六、测试运行

测试代码

import com.softwareClass.SplashClass;
import org.junit.jupiter.api.Test;

import java.io.IOException;

public class SplashClassTest {
    @Test
    public void testGenerateExercises(){
        try {
            SplashClass.main(new String[]{"Myapp.exe","-n","10","-r","10"});
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void testCheckAnswer(){
        try {
            SplashClass.main(new String[]{"Myapp.exe","-e","Exercises.txt","-a","Answer.txt"});
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

testGenerateExercises()测试结果

在当前目录下生成了两个文件Exercises.txt和Answer.txt


使用标准答案测试testCheckAnswer()

在生成的Grade.txt文档里全部都是正确的,经过数学验算也可得知答案没有出错
修改Answer.txt:答案(1,3,5,7)分别加1

使用修改后的答案测试testCheckAnswer()
(为了更好地对比,不加清除文本原来内容的处理逻辑)

生成一万条题目
修改测试代码

检查生成结果

标签:结对,项目,int,denominator,numerator,num,Fraction,new
From: https://www.cnblogs.com/CuteDucK/p/18435978

相关文章

  • 结对项目
    结对项目————四则运算的实现这个作业属于哪个课程https://edu.cnblogs.com/campus/gdgy/CSGrade22-34这个作业要求在哪https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230这个作业的目标设计一个四则运算生成器项目成员一梁俊轩31220045......
  • 自然语言处理实战项目:从理论到实现
    一、引言自然语言处理(NLP)是计算机科学、人工智能和语言学交叉的领域,旨在让计算机能够理解、处理和生成人类语言。随着互联网的飞速发展,大量的文本数据被产生,这为自然语言处理技术的发展提供了丰富的素材,同时也对其性能提出了更高的要求。在本文中,我们将详细阐述一个自然语......
  • 结对项目
    这个作业属于哪个课程https://edu.cnblogs.com/campus/gdgy/CSGrade22-12这个作业要求在哪里https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/homework/13221这个作业的目标结对合作完成项目两位同学的姓名许莹柔,学号:3222004684肖晓霞,学号:322200......
  • GitHub每日最火火火项目(9.27)
    项目名称:localsend/localsend项目介绍:“localsend/localsend”是一个极具价值的开源项目。它为用户提供了一种跨平台的文件传输替代方案,可媲美AirDrop。在当今数字化时代,人们常常需要在不同操作系统的设备之间传输文件,但并非所有设备都能使用AirDrop。这个项目的出......
  • Springboot大学生创新创业项目管理系统sg2u6(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,教师,专家,项目类别,项目申报,中期检查,中期评价,项目结题,结题评价开题报告内容一、研究背景与意义在当前的知识经济时代,创新创业已成为推动社会发展和提......
  • 软件工程结队项目:基于C++实现的自动生成小学四则运算的命令行程序
    这个作业属于哪个课程https://edu.cnblogs.com/campus/gdgy/CSGrade22-34这个作业要求在哪里https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230这个作业的目标<运用C++实现四则运算法则的命令行程序>团队成员1李梓灏3122004695团队成员2吴......
  • 快速创建SpringBoot项目
     1.使用SpringInitializr创建项目1.1.在线生成项目         访问SpringInitializr网站            选择项目的基本配置:Project:MavenProject或GradleProject(通常使用Maven)Language:JavaSpringBootVersion:......
  • 第二部分 项目结构、代码风格与标识符命名
    目录第5条使用得到公认且广泛使用的项目结构第6条提交前使用gofmt格式化源码第7条使用Go命名惯例对标识符进行命名第5条使用得到公认且广泛使用的项目结构第6条提交前使用gofmt格式化源码第7条使用Go命名惯例对标识符进行命名......
  • 建筑的抗震等级与建筑资质中哪些项目有关?
    在地震多发地带,建筑物的抗震性能是保障人民生命财产安全的关键因素。抗震等级作为建筑设计中的一个重要指标,与建筑资质紧密相关。建筑的抗震等级与建筑资质中以下项目有关:1.工程设计资质:抗震设计是建筑设计的重要组成部分,设计单位必须具备相应的设计资质,以确保其设计的建......
  • [微信小程序原创项目]基于Springboot+Vue+Uniapp的通用商城小程序、商城管理系统
    项目提供:完整源码+数据库sql文件+数据库表Excel文件关注我的B站:程序员阿水呀,带小白学习更多干货教程!1、项目功能描述本项目为双角色,用户和管理员,用户使用小程序前台,管理员使用web后台。1.1注册注册功能:填写用户名、密码进行注册。仅开放小程序端即用户端进行注册。......