四则运算生成器

BY-信安1班 叶湖倩(3216005170) 信安1班 叶钰羽(3216005171)

1. 项目介绍

源代码GitHub地址:https://github.com/yeyuyu/sizeyunsuan.git

该项目需求为实现一个自动生成小学四则运算题目的命令行程序,并且可以通过命令行参数控制生成题目的个数还有控制题中数值的范围,并满足一些其它的需求。我们的结对项目完成的需求如下:

需求 是否实现
使用 -n 参数控制生成题目的个数
使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围
生成的题目中计算过程不会产生负数
每道题目中出现的运算符个数不超过3个
程序一次运行生成的题目不能重复
当生成题目时,计算所有答案并存入执行程序的当前目录下
程序支持10000道题目的生成
判定答案对错并进行数量统计

2. 耗时预计

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 75
· Estimate · 估计这个任务需要多少时间 60 75
Development 开发 1760 2165
· Analysis · 需求分析 (包括学习新技术) 90 80
· Design Spec · 生成设计文档 60 45
· Design Review · 设计复审 (和同事审核设计文档) 60 90
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 45
· Design · 具体设计 360 300
· Coding · 具体编码 600 800
· Code Review · 代码复审 360 600
· Test · 测试(自我测试,修改代 200 150
Reporting 报告 150 135
· Test Report · 测试报告 60 45
· Size Measurement · 计算工作量 30 30
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 60
合计   1970 2375

3.解题思路

产生随机数-->生成表达式-->计算-->输出

4.设计实现过程

项目结构说明如下:

各类功能说明如下:

  • Main.class

主函数,调用其他功能模块实现-n,-r,-e命令。

  • CreateRandom.class

该类主要生成随机数,随机数分为分数,整数,若为分数则将其化简,实现数值和字符串之间的转换,并定义了分数的加减乘除。

  • CreateExpression.class

该类生成表达式。定义了四种操作符,随机取操作符,并调用CreateRandom.class取随机数,存入list数组,生成表达式 。

  • Calculate.class

该类主要实现计算功能。实现判负功能,并定义了表达式结果计算方法,即遇到括号,遇到连续的加减,乘除时的计算顺序。

  • OutPut.class

该类实现将表答式和答案在文件中输出,若已生成表达式文件,可实现将表达式与答案文件比对,输出比对结果。

5.代码说明

  • CreateRandom.class

1.将数字的字符串形式转换为整数、分数形式

public CreateRandom(String string) {                                    // 将数字的字符串形式转换为整数、分数形式
string = string.trim(); // 清除前后空格
int c = string.indexOf("'"); // 求带分数标志“'”的索引
int d = string.indexOf("/"); // 求分数标志“/”的索引
if (c != -1) { // 数字为带分数
int z = Integer.valueOf(string.substring(0, c)); //字符串子串
b = Integer.valueOf(string.substring(d + 1)); //取分母
a = z * b + Integer.valueOf(string.substring(c + 1, d)); //取分子
} else if (d != -1) { // 数字为真分数
b = Integer.valueOf(string.substring(d + 1));
a = Integer.valueOf(string.substring(0, d));
} else { // 数字为整数
a = Integer.valueOf(string);
b = 1;}
build(a, b);} //化简

 2.将数字的整数、分数形式转换成字符串形式

// 数字形式转换为字符串形式
public String toString() {
if (b == 1) {
return String.valueOf(a);
} else {
int i = a / b;
if (i != 0) {
return String.format("%d'%d/%d", i, a - b * i, b);
} else {
return String.format("%d/%d", a, b);}}}

3.定义分数的加减乘除

// 加法 a + b
public CreateRandom add(CreateRandom fraction) {
return new CreateRandom(this.a * fraction.b + fraction.a * this.b, this.b * fraction.b);}
// 减法 a - b
public CreateRandom subtraction(CreateRandom fraction) {
return new CreateRandom(this.a * fraction.b - fraction.a * this.b, this.b * fraction.b);}
// 乘法 a x b
public CreateRandom multiplication(CreateRandom fraction) {
return new CreateRandom(this.a * fraction.a, this.b * fraction.b);}
// 除法a/b
public CreateRandom division(CreateRandom fraction) {
return new CreateRandom(this.a * fraction.b, b * fraction.a);}
  • Calculate.class

定义表达式计算优先级
public static String getResult(CreateExpression expression) {           //定义表达式计算优先级
String string = expression.s;
String[] strings = string.split("\\s+"); //分隔,并放进数组
List<String> list = new ArrayList<String>();
for (int i = 0; i < strings.length; i++) {
list.add(strings[i]);}
if (string.indexOf("(") != -1) { //定义括号的优先级
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("="))
break;
if (list.get(i).equals("(")) {
list.set(i, calculate1(expression, list.get(i + 2), new CreateRandom(list.get(i + 1)), new CreateRandom(list.get(i + 3)))
.toString());
for (int j = 0; j < 4; j++) {
list.remove(i + 1);}}}} if (string.indexOf("×") != -1 || string.indexOf("÷") != -1) { //定义连续遇到乘除时的计算顺序
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("="))
break;
if (list.get(i).equals("×") || list.get(i).equals("÷")) {
list.set(i - 1, calculate1(expression, list.get(i), new CreateRandom(list.get(i - 1)), new CreateRandom(list.get(i + 1)))
.toString());
for (int j = 0; j < 2; j++) {
list.remove(i);}
i--;}}} if (string.indexOf("+") != -1 || string.indexOf("-") != -1) { //定义连续遇到乘除时的计算顺序
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("="))
break;
if (list.get(i).equals("+") || list.get(i).equals("-")) {
list.set(i - 1, calculate1(expression, list.get(i), new CreateRandom(list.get(i - 1)), new CreateRandom(list.get(i + 1)))
.toString());
for (int j = 0; j < 2; j++) {
list.remove(i);}
i--;}}}
return list.get(0);}
  • OutPut.class

1.生成表达式输出文件

public void outputExercises() {
try {
PrintWriter exercisesWriter = new PrintWriter(new FileWriter("Exercises.txt"));//创建具有指定文件名称且不带自动行刷新
PrintWriter answerWriter = new PrintWriter(new FileWriter("Answers.txt"));
for (int i = 1; i < titleNum + 1;) { //控制题目数量
CreateExpression expression = new CreateExpression(parameterRange);
String getresult = Calculate.getResult(expression);
String string = getresult;
System.out.println(expression.isWrong == false);
System.out.println(!(set.contains(string)));
if (expression.isWrong == false && !(set.contains(string))) {
set.add(string);
exercisesWriter.println(i + ". " + expression.toString());
answerWriter.println((i + ". " + string));
i++;}}
exercisesWriter.close();
answerWriter.close();
} catch (IOException e) {
e.printStackTrace();}
System.out.println("已经生成题目和答案");}

2.生成比对结果输出文件

    public void outputGrade(String exercisePath, String answerPath, String gradePath) {

        try {
BufferedReader exercisesReader = new BufferedReader(new FileReader(exercisePath));
BufferedReader answerReader = new BufferedReader(new FileReader(answerPath));
PrintWriter gradeWriter = new PrintWriter(new FileWriter(gradePath));
String exercises, answer;
int c = 0, w = 0;
StringBuilder correct = new StringBuilder("Correct: %d (");
StringBuilder wrong = new StringBuilder("Wrong: %d (");
while ((exercises = exercisesReader.readLine()) != null && (answer = answerReader.readLine()) != null) {
int exercisesPoint = exercises.indexOf("."); //索引
int answerPoint = answer.indexOf(".");
if (exercisesPoint != -1 && answerPoint != -1) {
int i = Integer.valueOf(exercises.substring(0, exercisesPoint).trim());
CreateExpression expression = new CreateExpression(exercises.substring(exercisesPoint + 1));
CreateRandom ans = new CreateRandom(answer.substring(answerPoint + 1));
String getresult = Calculate.getResult(expression);
String string = getresult;
if (string.equals(ans.toString())) {
c++;
correct.append(" " + i);
if (c % 30 == 0) {
correct.append("\r\n");}
} else {
w++;
wrong.append(" " + i);
if (w % 30 == 0) {
wrong.append("-r\n");}}}}
gradeWriter.println(String.format(correct.append(" )").toString(), c));
gradeWriter.println(String.format(wrong.append(" )").toString(), w));
gradeWriter.flush();
exercisesReader.close();
answerReader.close();
gradeWriter.close();
} catch (IOException e) {
e.printStackTrace();}
System.out.println("已经比较完成,并生成输出文件");}

6.测试运行

  • 输入参数-n为600,-r为100,窗口运行界面如下:

  • 生成的Exercises.txt和Answers.txt部分截图如下:

   

  • 输入-e Exercises.txt Answers.txt命令,窗口运行结果如下:

  • 比对Exercises.txt和Answers.txt,输出的比对结果Rrade.txt如下:

  • 故意写错几题答案,Grade.txt文件截图如下:

  • 测试生成10000道题目,Exercises.txt文件部分截图:

7.项目小结

首次尝试结对编程,刚开始在讨论功能设计时很顺利,沟通时没有遇到什么问题,但在实际编码时却遇到了许多问题。一开始各自编写代码,没有注释,导致看对方的代码耗时长或者看不懂。在编码阶段,我们分别编写不同的模块,当各自的功能模块编写完之后,遇到各模块调用出错,出现死循环等的问题,导致最后DEBUG找逻辑问题了花费大量时间。在编码伊始,未统一变量名,后续调整浪费了许多时间。通过此次合作,我们学会了分工合作,明白了代码注释和有效沟通的重要性。

软工作业-四则运算(java实现)BY叶湖倩,叶钰羽的更多相关文章

  1. 软工作业(JAVA)

    github传送门:https://github.com/hhg52516/WC.git 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序 ...

  2. 软工作业1—java实现wc.exe

    github项目地址 https://github.com/liyizhu/wc.exe WC 项目要求 基本功能列表: wc.exe -c file.c     //返回文件 file.c 的字符数 ...

  3. 软工作业-----Alpha版本第一周小结

            软工作业-----Alpha版本第一周小结   Part1.第一周周计划记录 姓名 学号 周前计划安排 每周工作记录 自我打分 yrz(队长) 1417 1.进行任务分析 2.任务分配 ...

  4. [软工作业]-软件案例分析-CSDN

    [软工作业]-软件案例分析-CSDN(app) 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业-软件案例分析 我在这个课程的目标是 ...

  5. 【软工作业&思考】关于软工的一些概念性理解暨第一次阅读作业

    概述 项目 内容 本次作业所属课程 2019BUAA软件工程 周二班 本次作业要求 第1次个人作业当然,比这个更重要百倍的还是实实在在的思考,这也是标题如此命名的原因 我在本课程的目标 在原有实践经验 ...

  6. 软工作业No.3--团队作业:甜美女孩出击!

    队名:甜美女孩 队员包括: 姓名 学号 身份 曾祎祺 3216005211 队长 邓画月 3216005212 队员 何颖琪 3216005213 队员 梁沛诗 3216005214 队员 梁子君 3 ...

  7. BUAA2020软工作业——提问回顾与个人总结

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾与个人总结 我在这个课程的目标是 进一步提高自己的编码能力,工程能力 这个作业在哪个具体方 ...

  8. 软工作业NO.2小学生线上杨永信——四则运算题目生成

    项目题目:实现一个自动生成小学四则运算题目的命令行程序 github地址:https://github.com/a249970271/Formula 驾驶员:梁沛诗 副驾驶:曾祎祺 项目说明 自然数: ...

  9. 软工作业No.1。Java实现WC.exe

    网址:https://github.com/a249970271/WC WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有w ...

随机推荐

  1. Eclipse插件--一次copy多个文件的相对路径路径

    因为工作需要, 在网上找了很多插件, 本来有个easyTools应该可以, 但下载文件好像没了. 只好自己动手搞了一个简单的, 暂时一个复制文件相对路径的功能, 有同样需求的童鞋, 可以试一下 plu ...

  2. web前端编码规范

    简要介绍 本文通过参考百度腾讯等前端编码规范(链接建文末),得出个人习惯的编码规范.个人编码规范采用在不影响可读性的情况下能省就省,尽量简洁,不需要就直接去掉. 最佳原则不管是个人编码规范还是团队编码 ...

  3. bootstrap基本使用

    bootstrap是封装了css和js代码实现酷炫的效果,所以使用的时候,比如说是列表效果,直接调用它本身定义的函数就ok了 静态文件 把href='..static/..'里面改为url_for静态 ...

  4. django联合查询

    假设A表的主键aid作为B表的外键,A表有属性name,那么想查询B表中name为abc的元素就可以这样写: B.objects.all().filter(aid__name = 'abc') __真 ...

  5. 操作JavaScript数组

    unshift:在数据首段添加元素. push: 在数组的末端添加元素. shift:移除并返回第一个元素,会影响 数组长度. pop:移除并返回最后一个元素.会影响 数组长度. delete  数组 ...

  6. 【Flask】Flask Cookie操作

    ### 什么是cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第 ...

  7. const,var,let笔记

    js中定义变量的方式有三种const.var.let const 作用域:全局作用域或函数作用域 定义的变量不可修改,且必须初始化 eg: const a= 1; a= 2; console.log( ...

  8. D3学习之动画和变换

    D3学习之动画和变换 ##(17.02.27-02.28) 主要学习到了D3对动画和缓动函数的一些应用,结合前面的选择器.监听事件.自定义插值器等,拓展了动画的效果和样式. 主要内容 单元素动画 多元 ...

  9. HDU 1241 油田

    这道题明明很简单但不知道为什么运行结果一直错,但提交却是对的!代码真是神奇,不过我猜测可能是提上给出的数据错了,可能提上给的数据m和n后多给了一个空格或回车,但题的数据没有 #include<s ...

  10. AtCoder Regular Contest 098

    AtCoder Regular Contest 098 C - Attention 题意 给定一个只包含"E","W"字符串,可以花一的花费使他们互相转换.选定 ...