绝对编程——小学四则运算

这个作业属于那个课程广工2023软件工程课程
作业要求作业要求
作业目标用绝对编程的方式实现自动生成小学四则运算题目的程序
成员赵光明——3121005104
钟海超——3121005105
仓库地址地址

1.PSP表格

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

2. 效能分析

效能分析
效能分析
从性能分析中可以看出,字符类调用比较多,这是因为在此次开发中,我们把所有的运算算式封装成对象进行存储以及运算

3. 设计实现过程

  1. 项目结构
    项目结构
  2. 项目运行流程
    项目运行流程

4. 代码说明

  1. 算式设计:把每一个算式存储为一个对象
public class OperatorConstant {
    public static final String ADD = "+";
    public static final String SUB = "-";
    public static final String MULTIPLY = "*";
    public static final String DIVIDE = "÷";
    public static final String LEFT_BRACKETS = "(";
    public static final String RIGHT_BRACKETS = ")";
    public static final String EQUAL_SIGN = "=";
    public static final HashMap<Integer,String> operatorMap = new HashMap<>();
    static{
        operatorMap.put(1, OperatorConstant.ADD);
        operatorMap.put(2, OperatorConstant.SUB);
        operatorMap.put(3, OperatorConstant.MULTIPLY);
        operatorMap.put(4, OperatorConstant.DIVIDE);
    }
}
  1. 生成算数式子
public class ArithmeticProblemGenerator {
    public MathProblem generateOneMathProblem(int range) {
        MathProblem mathProblem = new MathProblem();
        //获得随机运算法数量
        int operatorNum = RandomProblemUtils.getRandomNum(1,3);
        List<String> operatorList = new ArrayList<String>();
        String operator = null;
        //给运算符赋值
        for (int i = 0; i < operatorNum ; i++) {
            operator = OperatorConstant.operatorMap.get((Integer) RandomProblemUtils.getRandomNum(1, 4));
            operatorList.add(operator);
        }
        //给运算值赋值
        List<String> numList = new ArrayList<String>();
        int flag = 0;
        for (int i = 0; i < operatorList.size()+1 ; i++) {
            flag = RandomProblemUtils.getRandomNum(0,1);
            if(flag == 0){
                //生成分数
                numList.add(RandomProblemUtils.generateFraction(range));
            }else {
                //生成自然数
                numList.add(RandomProblemUtils.generateNaturalNumber(range));
            }
        }
        mathProblem.setData(numList);
        mathProblem.setOperator(operatorList);
        mathProblem.setProblemString(generateExerciseStr(mathProblem));
        mathProblem.setAnswer(getAnswer(mathProblem));
        return mathProblem;
    }

    /**
     * 根据MathProblem对象获取符合题目格式的输出
     * @param mathProblem 题目
     * @return
     */
    private static String generateExerciseStr(MathProblem mathProblem) {
        Queue<String> queue = new LinkedList<>();
        List<String> operators = mathProblem.getOperator();
        List<String> numbers = mathProblem.getData();
        for (int i = 0; i < numbers.size() ; i++) {
            queue.add(numbers.get(i));
        }
        String exerciseStr = "";
        for (int i = 0; i < operators.size() ; i++) {
            String operator = operators.get(i);
            String num1 = queue.remove();
            String num2 = queue.remove();
            if(i != operators.size()-1){
                exerciseStr = OperatorConstant.LEFT_BRACKETS+num1+operator+num2+OperatorConstant.RIGHT_BRACKETS;
            }else {
                exerciseStr = num1+operator+num2;
            }
            queue.add(exerciseStr);
        }
        StringBuilder sb = new StringBuilder("").append(queue.remove()).append("=");
        return sb.toString();
    }
    /**
     * 获取题目答案
     * @param mathProblem  题目
     * @return
     */
    private static String getAnswer(MathProblem mathProblem) {
        List<String> numbers = mathProblem.getData();
        List<String> operators = mathProblem.getOperator();
        Queue<String> queue = new LinkedList<>();
        for (int i = 0; i < numbers.size() ; i++) {
            String s = numbers.get(i);
            if(RandomProblemUtils.checkFraction(s) == 3){
                s = RandomProblemUtils.DaiFractionToFalseFraction(s);
            }
            queue.add(s);
        }
        for (int i = 0; i < operators.size() ; i++) {
            String operator = operators.get(i);
            String num1 = queue.remove();
            String num2 = queue.remove();
            String answer = RandomProblemUtils.BinocularOperation(num1,num2,operator);
            if(answer == null){
                mathProblem.setAnswer(null);
                return "";
            }
            if(RandomProblemUtils.checkFraction(answer) == 2){
                answer = RandomProblemUtils.FalseFractionToDaiFraction(answer);
            }
            queue.add(answer);
        }
        return queue.remove();
    }

    /**
     * 根据题目数量和范围获取练习题
     * @param mathProblemsNum  生成题目数量
     * @param range     题目运算数的范围
     * @return         所有题目
     */
    public List<MathProblem> getMathProblemList(int mathProblemsNum, int range) {
        List<MathProblem> mathProblemList = new ArrayList<>();
        for (int i = 1; i <= mathProblemsNum; ++i){
            MathProblem mathProblem = generateOneMathProblem(range);
            mathProblem.setTitleNumber(i);
            mathProblemList.add(mathProblem);
        }
        return mathProblemList;
    }
}
  1. 异常处理
public class MathException extends RuntimeException{
    public MathException() {}

    public MathException(String message) {
        super(message);
    }
}

5. 测试运行

  1. 根据要求生成测试用例及答案
    测试用例
    答案
  2. 进行答案对比
    答案对比
  3. 支持最大生成10000道题
    10000道题

6. 项目小结

在本次结对学习的过程中我们合力解决的许多问题,在遇到困难时互相帮助,互补短处,如果遇到了两个人共同的盲区也可以一起上网寻找解决思路。这比个人编程效率高了很多,毕竟人多力量大。而且结对编程不仅仅是提升了彼此的能力,同样也加强了我们的沟通能力,这同样是作为程序员所必备的素养。当然最开始也存在分工不太合理的情况,导致在某些板块卡住太久。希望在以后的学习中还能继续与彼此合作,互相讨论、纠错,互相分享学习经验,在实践操作中不断提升自己。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值