本次作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2166

github远程仓库的地址:https://github.com/mingbiaoleung/FourOperation

第一部分:要求

1.作业需求:任何编程语言都可以,命令行程序接受一个数字输入,然后输出相应数目的四则运算题目和答案。例如输入数字是 30, 那就输出 30 道题目和答案。 运算式子必须至少有两个运算符,运算数字是在 100 之内的正整数,答案不能是负数。

2.拓展要求

1) 要求能出和真分数 (二分之一, 十二分之五,等)相关的练习题。

2) 并且要求能处理用户的输入,并判断对错,打分统计。 要求能处理用户输入的真分数, 如 1/2, 5/12 等。

初步拟定要实现的功能后,估计一下自己需要花多长时间。编程过程中记录自己实际用了多长时间。

然后和同学们比较一下各自程序的功能、实现方法的异同等等。

第二部分:设计

1.需求分析

   (1)随机产生 100 之内的正整数或者真分数的题目。
   (2)答案不能是负数。
   (3)题目数根据用户而定。
     (4)运算式子必须至少有两个运算符。
.    (5)判断用户输入值的对错,并给出用户的正确题目数和分数。

2.功能设计

1.根据用户要求的题目数,循环num次输出随机四则运算。

2.判断用户输入值是否正确,并给出正确题目数。

3.答案不能小于0,小于0就重新输出题目。

4.能出和真分数 (二分之一, 十二分之五,等)相关的练习题。

3.代码规范

  命名规范:使用匈牙利命名法

  程序风格:程序按照阶梯式编写,括号习惯使用其一个括号在语句后面,结尾括号另占一行

  注释规范:函数头的注释(“功能”,“返回值”),在一些关键的语句上面进行注释

第三部分:代码实现

总体设计:

◻随机产生100以内的正整数,运算符号以及正整数和运算符号的数量,通过调参可以调整生成正整数和运算符号的数量,四则运算乘除和加减优先级别:先乘除后加减,在计算函数中遍历运算符数组中乘除符号后进行优先计算,之后再对乘除计算之后的运算数进行相加减运算。

◻真分数设计:随机生成真分数,分子与分母大小范围在1-20随机生成,范围可以通过改变参数进行调整,分数约分后用对象进行存储。可以通过改变参数对分数运算数的数量(计算难度较大,这里使用生成两个运算数进行运算)。分数运算时,优先乘除后再相加减,会对最终计算结果进行约分到最简。

◻当随机产生的正整数运算题和真分数运算题计算结果为负数则递归重新生成运算题,直至结果是大于零时产生题目并打印在控制台上,用户输入答案,答案与结果匹配正确即统计正确题数,错误的输出打印正确结果,当全部运算题做完后输出统计结果以及分数。分数计算公式: 100 * (正确数 / 总题数)。

主要代码:

  1. // 生成运算公式并计算正确结果,将最终的存入List中
  2. public void generateFormula() {
  3. Random random = new Random();
  4. int operationNum = random.nextInt(3) + 3; //运算数的个数
  5. int operatorNum = operationNum - 1; //运算符的个数
  6.  
  7. List<String> newOperators;
  8. List<Integer> newOperations;
  9. int newAnswer;
  10. //计算运算式答案
  11. do {
  12. List<String> operators = storeOpInList(operatorNum);
  13. List<Integer> operations = operations(operationNum, operators);
  14. newOperators = deepCopy(operators);
  15. newOperations = deepCopy(operations);
  16. newAnswer = generateCorrectAnswer(operators, operations);
  17. } while (newAnswer < 0);
  18.  
  19. StringBuilder stringBuilder = new StringBuilder();
  20. for (int i = 0; i < operationNum - 1; i++)
  21. stringBuilder.append(newOperations.get(i) + " " + newOperators.get(i) + " ");
  22. stringBuilder.append(newOperations.get(operationNum - 1) + " = ");
  23. System.out.println(stringBuilder.toString());
  24. operatorExpressionList.add(stringBuilder.toString());
  25. correctAnswerList.add(String.valueOf(newAnswer));
  26. }
  1. /**
  2. * @author: 梁铭标
  3. * @Date:2018.10.10
  4. * @Content:可序列化真分数对象
  5. */
  6. public class Fraction implements Serializable {
  7. private static final long serialVersionUID = -3245478690496182643L;
  8. private int numerator; //分子
  9. private int denominator; //分母
  10.  
  11. public Fraction(int numerator, int denominator) {
  12. this.numerator = numerator;
  13. this.denominator = denominator;
  14. }
  15.  
  16. public int getNumerator() {
  17. return numerator;
  18. }
  19.  
  20. public int getDenominator() {
  21. return denominator;
  22. }
  23.  
  24. public void setNumerator(int numerator) {
  25. this.numerator = numerator;
  26. }
  27.  
  28. public void setDenominator(int denominator) {
  29. this.denominator = denominator;
  30. }
  31. }

计算真分数运算式的正确结果

  1. // 计算真分数运算式的正确结果
  2. public Fraction generateCorrectAnswer(List<String> operators, List<Fraction> operations) {
  3. //遍历运算符容器,完成乘除运算
  4. for (int i = 0; i < operators.size(); i++) {
  5. String operator = operators.get(i);
  6. if (operator.equals("*") || operator.equals("/")) {
  7. operators.remove(i); //乘除符号将其从集合中移除
  8. Fraction fractionLeft = operations.remove(i); //拿运算符左侧的数字
  9. Fraction fractionRight = operations.remove(i); //拿运算符右侧的数字
  10. if (operator.equals("*"))
  11. operations.add(fractionMultiple(fractionLeft, fractionRight));
  12. else
  13. operations.add(fractionDivide(fractionLeft, fractionRight));
  14. i--; //运算符容器的指针回到原来的位置,防止跳过下一个运算符
  15. }
  16. }
  17.  
  18. //遍历运算符容器,完成加减运算,当运算符容器为空时,运算结束
  19. while (!operators.isEmpty()) {
  20. String operator = operators.remove(0);
  21. Fraction fractionLeft = operations.remove(0);
  22. Fraction fractionRight = operations.remove(0);
  23. if (operator.equals("+"))
  24. fractionLeft = fractionAdd(fractionLeft, fractionRight);
  25. else
  26. fractionLeft = fractionSubtract(fractionLeft, fractionRight);
  27. operations.add(0, fractionLeft);
  28. }
  29.  
  30. //返回计算结果
  31. return operations.get(0);
  32. }

该作业的程序总引擎

  1. /**
  2. * @author: 梁铭标
  3. * @Date:2018.10.10
  4. * @Content:正整数和真分数总引擎
  5. */
  6. public class ExecutionEengine {
  7. public static void main(String[] args) {
  8. SimpleFourOperation simpleFourOperation = new SimpleFourOperation();
  9. simpleFourOperation.init();
  10. FractionOperation fractionOperation = new FractionOperation();
  11. Scanner scanner = new Scanner(System.in);
  12. System.out.print("请输入生成四则运算题目的个数:");
  13. int titleNum = handleUserInput(scanner);
  14.  
  15. //随机生成正整数和分数的题目数量
  16. Random random = new Random();
  17. int simpleFourOperationNum = random.nextInt(titleNum) + 1;
  18. int FractionOperationNum = titleNum - simpleFourOperationNum;
  19.  
  20. //分别获取用户做对相应题目的正确数
  21. int simpleFourOpTrueNum = simpleFourOperation.generateSimpleFourOpExp(simpleFourOperationNum, scanner);
  22. int fractionOpTrueNum = fractionOperation.generateFractionOpExp(FractionOperationNum, scanner);
  23.  
  24. //计算总分数
  25. int trueNum = simpleFourOpTrueNum + fractionOpTrueNum;
  26. int falseNum = titleNum - trueNum;
  27. int score = 100 * trueNum / titleNum;
  28.  
  29. System.out.println("恭喜你完成这次练习,题目总数:" + titleNum + ", 你做对了" + trueNum + "道题,"
  30. + "做错了" + falseNum + "道题, " + "总分数为" + score + ", 继续加油!");
  31. }
  32.  
  33. public static int handleUserInput(Scanner scanner) {
  34. int titleNum;
  35. do {
  36. titleNum = scanner.nextInt();
  37. if (titleNum > 0)
  38. break;
  39. else {
  40. System.out.println("输入有误,不能输入非法字符以及小于0,请重新输入!");
  41. System.out.println("请输入生成四则运算题目的个数:");
  42. }
  43. } while (!(titleNum > 0));
  44. return titleNum;
  45. }
  46. }

运行结果:

第四部分:问题及解决方法

1.怎么解决先乘除后加减的问题?

先乘除后加减,在计算结果函数中遍历运算符数组中乘除符号后,在从存储运算数数组获取相对应的运算数进行优先计算,之后再对乘除计算之后的运算数进行相加减运算。

2.结果可以为负数,试了很多方法,最终找了一个好的方法?

定义一个在结果为负数和下一次循环的变量,用来控制题目数量,大于0就输出题目。

3.分数怎么约分?

将分子和分母的最小值的数值,从大到小去除分子和分母,如果能够同时被整除,则以此数值约分。

总结:

通过这次练习,明白了一个程序开发是一件不容易的事情,没有好的知识功底是无法创造出高质量高拓展的软件。天生我才必有用,千金散尽还复来,我会用这句话激励自己用功学习。

第五部分:个人软件过程耗时估计与统计表

PSP2.1 Personal Software Process Stages 预计hour 实际hour
Planning 计划 0.1 0.3
· Estimate 估计这个任务需要多少时间 5 9.0
Development 开发 0.3 6.0
· Analysis 需求分析 (包括学习新技术) 0.4 0.4
· Design Spec 生成设计文档 0.3 0.3
· Design Review 设计复审 0.2 0.3
· Coding Standard 代码规范 0.1 0.5
· Design 具体设计 0.3 0.3
· Coding 具体编码 2 2
· Code Review 代码复审 0.3 0.5
· Test 测试(自我测试,修改代码,提交修改) 0.3 1.0

Java小学四则运算的更多相关文章

  1. java实现自动生成小学四则运算——朱庭震,詹祺豪

    组员:朱庭震,詹祺豪 Github地址:https://github.com/ztz1998/second/tree/master 1题目:实现一个自动生成小学四则运算题目的命令行程序. 2说明: 自 ...

  2. 小学四则运算练习(JAVA编写)

    源码在Github的仓库主页链接地址:https://github.com/rucr9/rucr 看到这个题目,大概很多人会发出“切,这也太简单了吧!有必要小题大做?”的感叹!是的,仅仅作为一道数学运 ...

  3. 小学四则运算APP 最后阶段

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 这次发布的是我们APP的最终版本!图片背景有根据用户需求改变!还增加了草稿纸运算的画布功能! 运行结果如下: package com.ex ...

  4. 小学四则运算APP 第三阶段冲刺-第一天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第三次冲刺阶段时间:12.12~12.19 本次发布的是音乐播放功能,可以根据用户需求一边播放音乐一边做题,也拥有暂停播放音乐的功能,增强 ...

  5. 小学四则运算APP 第二阶段冲刺-第五天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是判断题代码,已经实现部分功能,,但是美中不足的是判断错误 panduanset.j ...

  6. 小学四则运算APP 第二次冲刺 第四天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是合并后的选择题功能界面的设置: ChoiceSet.java: package c ...

  7. 小学四则运算APP 第二阶段冲刺-第三天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是判断题的部分代码 panduanset.java import com.examp ...

  8. 小学四则运算APP 第二个冲刺 第一天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是已完成的功能二(选择题): ChoiceActivity.java: packag ...

  9. 小学四则运算APP 第一个冲刺 第八天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第一次冲刺阶段时间:11.17~11.27 本次发布的是还未完成的功能二(选择题): ChoiceActivity.java: packa ...

随机推荐

  1. 分布式任务调度平台XXL-JOB快速使用与问题总结

    1.XXL-JOB简介 XXL-JOB is a lightweight distributed task scheduling framework. It's core design goal is ...

  2. 深入V8引擎-写在前面

    这一篇不打算讲技术,聊点别的吧,写这个的原因主要是看到了我博客园的签名,开始这个最终源码系列前想说点什么. 转行前端(达成) 入行1年vue源码(达成).webpack源码(半达成) 入行2年争取读通 ...

  3. Go 笔记之如何防止 goroutine 泄露

    今天来简单谈谈,Go 如何防止 goroutine 泄露. 概述 Go 的并发模型与其他语言不同,虽说它简化了并发程序的开发难度,但如果不了解使用方法,常常会遇到 goroutine 泄露的问题.虽然 ...

  4. mac pro使用2K(2056*1440)设置屏幕解决方法

    参考: https://www.jianshu.com/p/40cee8ab3d0f https://www.zhihu.com/question/35300978 在点击ok后,发现并不能保存.或者 ...

  5. vue展示md文件,前端读取展示markdown文件

    方案1:每次都需要重新打包,每次修改都需要build 直接使用require + v-html: 核心代码如下: 1. 首先需要添加MD文件的loader就是 markdown-loader npm ...

  6. cocos2d-js中jsc逆向为js攻略

    笔记: 主要发现有两个工具 存档记录一下 https://github.com/OEDx/cocos-jsc-endecryptor  python的 解密需要秘钥 推荐这个: https://git ...

  7. c# datagridview导出Excel文件 问题

    今天vs2010c#开发做datagridview导出Excel文件时,发现一个问题,和大家探讨一下: 第一种方式:写流的方式 private void button_Excel_Click(obje ...

  8. elasticsearch组合多条件查询实现restful api以及java代码实现

    原文:http://blog.java1234.com/blog/articles/372.html elasticsearch组合多条件查询实现restful api以及java代码实现 实际开发中 ...

  9. Mysql-修改用户连接数据库IP地址和用户名

    将用户连接数据库(5.7.14-7)的IP地址从 10.10.5.16   修改为 10.11.4.197 Mysql> rename user 'username'@'10.10.5.16' ...

  10. Mysql读写分离操作

    环境:两台centos环境,安装mysql(mariadb) web网站的优化: 缓存技术 数据库缓存 redis 文件缓存 图片 fastdfs 负载均衡 nginx 数据库主从备份,读写分离 图解 ...