一 、Github项目地址:https://github.com/mushan520/Four-fundamental-rules-java.git

                                 或   https://github.com/SAH2019/as

 

二、PSP表格:

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60   45
· Estimate · 估计这个任务需要多少时间 60 45
Development 开发 1260 1515
· Analysis · 需求分析  60   90  
· Design Spec · 生成设计文档 60 60
· Design Review · 设计复审  30 45
· Coding Standard · 代码规范 30 60
· Design · 具体设计 90 90
· Coding · 具体编码 900 1080
· Code Review · 代码复审 30 30
· Test · 测试(自我测试,修改代码,提交修改) 60 90
Reporting 报告 100 140
· Test Report · 测试报告 30 50
· Size Measurement · 计算工作量 30 50
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 40 40
合计   1420 1700

三:实现过程

1.因为涉及到分数的相关运算,所以单独设计了一个分数类Fraction,里面实现了分数的加减乘除计算以及分数的显示,以供给其他的类和方法调用

 2.FormulaMaker中展示了整个项目的实现过程:1)随机生成整数或者分数-->2)随机生成四则运算的符号-->3)将生成的运算数和符号连接成算式-->4)对算式进行结果的计算-->5)分别输出结果和算式到文件中。

3.我们所做的程序和老师的要求还有一定的差距,比如分数的表示,目前我们的程序生成的结果,都是以分数形式表示的,比如0/2  ,2/1或者是8/3这种本该用2‘2/3表示的结果,无法正确的按要求显示,这是我们技术上的不成熟导致的,很遗憾。

  4.以下的导图显示了程序的方法结构。

 

四:代码说明

1.   FormulaMaker :主要的一个类:用来完成生成随机的算式,以及算式的计算,还有算式和答案的输出

  1. 1 package creater;
  2. 2
  3. 3 import java.io.File;
  4. 4 import java.io.FileWriter;
  5. 5 import java.io.PrintStream;
  6. 6 import java.util.HashSet;
  7. 7 import java.util.Random;
  8. 8 import java.util.Stack;
  9. 9
  10. 10 public class FormulaMaker {
  11. 11 private int numRange;
  12. 12 private int questionsNum;
  13. 13
  14. 14 public FormulaMaker(int numRange, int questionsNum) {
  15. 15 this.numRange = numRange;
  16. 16 this.questionsNum = questionsNum;
  17. 17 makeFormula();
  18. 18 HashSet<String> set = makeFormulas();
  19. 19 Fraction[] arr = getAnswers(set);
  20. 20 outputFormula(set);
  21. 21 outputAnswers(arr);
  22. 22
  23. 23 }
  24. 24
  25. 25 // 获取随机整数
  26. 26 public int getRandomNumber() {
  27. 27 Random rand = new Random();
  28. 28 int RandomNum = rand.nextInt(this.numRange);
  29. 29 if (RandomNum == 0)
  30. 30 RandomNum = RandomNum + 1;
  31. 31 return RandomNum;
  32. 32 }
  33. 33 //获取随机分数
  34. 34 public Fraction getRandomFraction() {
  35. 35 Fraction a = new Fraction(getRandomNumber(), getRandomNumber());
  36. 36 return a;
  37. 37
  38. 38 }
  39. 39
  40. 40 // 获取随机运算符号
  41. 41 public String getRandomSign() {
  42. 42 Random rand = new Random();
  43. 43 String[] operations = { "+", "-", "*", "/" };
  44. 44 return operations[rand.nextInt(4)];
  45. 45 }
  46. 46
  47. 47 public String makeFormula() {
  48. 48 String formula = "";
  49. 49 for (int i = 0; i < 4; i++) {
  50. 50 if (i >= 3) {
  51. 51 {
  52. 52 Random rand = new Random();
  53. 53 int a = rand.nextInt(2);
  54. 54 switch (a) {
  55. 55 case 0:
  56. 56 formula += this.getRandomNumber();
  57. 57 break;
  58. 58 case 1:
  59. 59 formula += getRandomFraction();
  60. 60 break;
  61. 61 }
  62. 62 }
  63. 63 continue;
  64. 64 }
  65. 65 Random rand = new Random();
  66. 66 int a = rand.nextInt(2);
  67. 67 switch (a) {
  68. 68 case 0:
  69. 69 formula += this.getRandomNumber() + " " + this.getRandomSign() + " ";
  70. 70 break;
  71. 71 case 1:
  72. 72 formula += this.getRandomFraction() + " " + this.getRandomSign() + " ";
  73. 73 break;
  74. 74 }
  75. 75
  76. 76 }
  77. 77 return formula;
  78. 78 }
  79. 79
  80. 80 // 生成算式集合
  81. 81 public HashSet<String> makeFormulas() {
  82. 82 HashSet<String> set = new HashSet<String>();
  83. 83 while (set.size() < this.questionsNum) {
  84. 84 String formula = this.makeFormula();
  85. 85 set.add(formula);
  86. 86 }
  87. 87 return set;
  88. 88 }
  89. 89
  90. 90
  91. 91 // 比较运算优先级
  92. 92 public int compare(String operator1, String operator2) {
  93. 93 int res = 0;
  94. 94 switch (operator1) {
  95. 95 case "+":
  96. 96 case "-":
  97. 97 if (operator2.equals("+") || operator2.equals("-") || operator2.equals("*") || operator2.equals("/")) {
  98. 98 res = 1;
  99. 99 } else {
  100. 100 res = -1;
  101. 101 }
  102. 102 break;
  103. 103 case "*":
  104. 104 case "/":
  105. 105 if (operator2.equals("*") || operator2.equals("/")) {
  106. 106 res = 1;
  107. 107 } else {
  108. 108 res = -1;
  109. 109 }
  110. 110 break;
  111. 111 }
  112. 112 return res;
  113. 113 }
  114. 114
  115. 115
  116. 116 // 生成算式结果
  117. 117 public Fraction getAnswer(String formula) {
  118. 118
  119. 119 int length = 0;
  120. 120 String[] formulaArr = formula.split(" ");
  121. 121 String operators = "+-*/";
  122. 122 Stack<Fraction> opNumbers = new Stack<Fraction>();
  123. 123 Stack<String> opOperators = new Stack<String>();
  124. 124 opOperators.add("#");// 字符栈中存储个#号,防止栈空
  125. 125 while (length < formulaArr.length) {
  126. 126 String op = formulaArr[length++];
  127. 127 if (operators.indexOf(op) > -1) {// 若是运算符,判断优先级
  128. 128 String sign = opOperators.peek();
  129. 129 int priority = compare(op, sign);// 要入栈的跟栈顶的相比
  130. 130 if (priority >= 0) {// 如果要入栈的运算符高或者相等,出栈两个数字,和之前的运算符,计算后,将数字入栈,将字符入栈
  131. 131 opNumbers.add(compute(opOperators, opNumbers));
  132. 132 opOperators.add(op);
  133. 133 } else {// 入栈运算符优先级低,直接入栈
  134. 134 opOperators.add(op);
  135. 135 }
  136. 136 continue;
  137. 137 }
  138. 138 // 若是数字,则入栈
  139. 139 if (op.matches("\\d+/\\d+")) {
  140. 140 String[] strs = op.split("/");
  141. 141 int fenZi = Integer.parseInt(strs[0]);
  142. 142 int fenMu = Integer.parseInt(strs[1]);
  143. 143 opNumbers.add(new Fraction(fenZi, fenMu));
  144. 144 } else {
  145. 145 int fenZi = Integer.parseInt(op);
  146. 146 opNumbers.add(new Fraction(fenZi, 1));
  147. 147 }
  148. 148
  149. 149 }
  150. 150 while (opOperators.peek() != "#") {
  151. 151 opNumbers.add(compute(opOperators, opNumbers));
  152. 152 }
  153. 153 Fraction lastResult = null;
  154. 154 String resultArr = opNumbers.pop()+"";
  155. 155 if (resultArr.matches("-?\\d+/\\d+")) {
  156. 156 String[] strs2 = resultArr.split("/");
  157. 157 int lastFenZi = Integer.parseInt(strs2[0]);
  158. 158 int lastFenMu = Integer.parseInt(strs2[1]);
  159. 159 lastResult=changeFraction(lastFenZi,lastFenMu);
  160. 160
  161. 161 }
  162. 162 return lastResult;
  163. 163
  164. 164 }
  165. 165
  166. 166
  167. 167 //给分数约分
  168. 168 public Fraction changeFraction(int a,int b) {
  169. 169 if(a < 0) {
  170. 170 a = -a;
  171. 171 int min = a < b ? a : b;
  172. 172 for (int i = min;i >= 1;i --) {
  173. 173 if (a % i == 0 && b % i == 0) {
  174. 174 a=a/i;
  175. 175 b=b/i;
  176. 176 break;
  177. 177 }
  178. 178
  179. 179 }
  180. 180 return new Fraction(-a,b) ;
  181. 181 }
  182. 182
  183. 183 int min = a < b ? a : b;
  184. 184 for (int i = min;i >= 1;i --) {
  185. 185 if (a % i == 0 && b % i == 0) {
  186. 186 a=a/i;
  187. 187 b=b/i;
  188. 188 break;
  189. 189 }
  190. 190
  191. 191 }
  192. 192 return new Fraction(a,b) ;
  193. 193
  194. 194 }
  195. 195
  196. 196
  197. 197
  198. 198 // 算式求值
  199. 199 public Fraction compute(Stack<String> opOperators, Stack<Fraction> opNumbers) {
  200. 200 Fraction num2 = opNumbers.pop();
  201. 201 Fraction num1 = opNumbers.pop();
  202. 202 String _op = opOperators.pop();
  203. 203 Fraction result = null;
  204. 204 switch (_op) {
  205. 205 case "+":
  206. 206 result = num1.add(num2);
  207. 207 break;
  208. 208 case "-":
  209. 209 result = num1.sub(num2);
  210. 210 break;
  211. 211 case "*":
  212. 212 result = num1.multiply(num2);
  213. 213 break;
  214. 214 case "/":
  215. 215 result = num1.div(num2);
  216. 216 break;
  217. 217 }
  218. 218 return result;
  219. 219 }
  220. 220
  221. 221
  222. 222 // 生成算式结果数组
  223. 223 public Fraction[] getAnswers(HashSet<String> set) {
  224. 224 Fraction[] arr = new Fraction[set.size()];
  225. 225 int i = 0;
  226. 226 for (String str : set) {
  227. 227 arr[i++] = getAnswer(str);
  228. 228 }
  229. 229 return arr;
  230. 230 }
  231. 231
  232. 232 // 输出算式到文件
  233. 233 public String outputFormula(HashSet<String> set) {
  234. 234 File file = new File("Exercises.txt");
  235. 235 try {
  236. 236 int b = 1;
  237. 237 PrintStream ps1 = new PrintStream(file);
  238. 238 for (String str : set) {
  239. 239
  240. 240 ps1.println(b + ". " + str + "=");
  241. 241 b++;
  242. 242 }
  243. 243 ps1.close();
  244. 244 } catch (Exception e) {
  245. 245 System.out.println("Error" + e.getMessage());
  246. 246 System.exit(0);
  247. 247 }
  248. 248 return file.getAbsolutePath();
  249. 249 }
  250. 250
  251. 251 // 输出答案到文件
  252. 252 public String outputAnswers(Fraction[] arr) {
  253. 253 File file = new File("Answers.txt");
  254. 254 try {
  255. 255 PrintStream ps2 = new PrintStream(file);
  256. 256 for (int i = 0; i < arr.length; i++) {
  257. 257 ps2.print(i + 1 + ". ");
  258. 258 ps2.println(arr[i]);
  259. 259 }
  260. 260 ps2.close();
  261. 261 } catch (Exception e) {
  262. 262 System.out.println("Error" + e.getMessage());
  263. 263 System.exit(0);
  264. 264 }
  265. 265 return file.getAbsolutePath();
  266. 266 }
  267. 267
  268. 268 }

2.     Fraction  分数类,计算分数的加减乘除以及显示分数:

  1. 1 package creater;
  2. 2
  3. 3 public class Fraction {
  4. 4
  5. 5 int fenzi;
  6. 6 int fenmu;
  7. 7
  8. 8 public Fraction(int fenzi, int fenmu) {
  9. 9 if (fenmu == 0) {
  10. 10 throw new IllegalArgumentException("分母不能为0");
  11. 11 }
  12. 12 this.fenzi = fenzi;
  13. 13 this.fenmu = fenmu;
  14. 14 }
  15. 15
  16. 16 // 分数的加法
  17. 17 public Fraction add(Fraction other) {
  18. 18 int fm = this.fenmu * other.fenmu;
  19. 19 int fz = this.fenzi * other.fenmu + other.fenzi * this.fenmu;
  20. 20 return new Fraction(fz, fm);
  21. 21 }
  22. 22
  23. 23 // 分数的减法
  24. 24 public Fraction sub(Fraction other) {
  25. 25 int fm = this.fenmu * other.fenmu;
  26. 26 int fz = this.fenzi * other.fenmu - other.fenzi * this.fenmu;
  27. 27 return new Fraction(fz, fm);
  28. 28 }
  29. 29
  30. 30 // 分数的乘法
  31. 31 public Fraction multiply(Fraction other) {
  32. 32 int fm = this.fenmu * other.fenmu;
  33. 33 int fz = this.fenzi * other.fenzi;
  34. 34 return new Fraction(fz, fm);
  35. 35 }
  36. 36
  37. 37 // 分数的除法
  38. 38 public Fraction div(Fraction other) {
  39. 39
  40. 40 int fm = this.fenmu * other.fenzi;
  41. 41 int fz = this.fenzi * other.fenmu;
  42. 42 return new Fraction(fz, fm);
  43. 43 }
  44. 44
  45. 45 // 分数的显示
  46. 46 public String toString() {
  47. 47
  48. 48
  49. 49
  50. 50 return fenzi + "/" + fenmu;
  51. 51 }
  52. 52
  53. 53
  54. 54 }
  1. 3.creater 类包含主方法,程序的开始。
  1. 1 package creater;
  2. 2
  3. 3 import java.util.Scanner;
  4. 4
  5. 5 public class creater {
  6. 6
  7. 7 public interface Fraction {
  8. 8
  9. 9 }
  10. 10
  11. 11 public static void main(String[] args) {
  12. 12 // TODO 自动生成的方法存根
  13. 13 long startTime = System.currentTimeMillis();
  14. 14 Scanner choose = new Scanner(System.in);
  15. 15 System.out.println("************************************欢迎来到四则运算生成器******************************************");
  16. 16 System.out.println("请选择生成题目数量:");
  17. 17 int questionsNum = choose.nextInt();
  18. 18 System.out.println("请输入算术范围:");
  19. 19 int numRange = choose.nextInt();
  20. 20
  21. 21 new FormulaMaker(numRange, questionsNum);
  22. 22 System.out.println("题目文件生成完毕!");
  23. 23 long endTime = System.currentTimeMillis();
  24. 24 System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
  25. 25 }
  26. 26
  27. 27 }

五:测试结果

结果一:测试结果比较小的时候(如生成20道题,算数在10以内)

控制台显示内容:

1.生成的算式文件--Exercises.txt

2.生成的答案文件--Answers.txt

结果二:程序能支持一万道题目的生成

控制台显示内容:

1.生成的算式文件--Exercises.txt

2.生成的答案文件--Answers.txt

六:项目小结

  本次的项目和上次相比有许多不同的地方,在项目完成后,做出以下结论:第一:这一次是两个人一同做一个项目,这样会比一个人单独做会简单一些。毕竟合作的作用就是1+1>2 。但是两个人合作也会有一些弊端,比如两个人的分工合作的调度是一个问题。第二:这是第二次的作业,明显的比上一次有了更多的做项目的经验,但是却发现了新的问题,就是编程知识的不足,这是项目经验弥补不了的,比如在大脑中构思好了某一个方法的流程和结构,但是总会在一些小细节上卡住,虽然说是小细节,但是影响也是巨大的。毕竟程序这种东西错了一个标点符号都是不可行的。第三:程序的方法之间会有紧密的联系,牵一发而动全身,因此后期的修改工作也是比较复杂。总而言之,提升自己的知识储备是当务之急!

项目作者:朱伟彬3117004639      商爱虎3117004626

结对编程(-java-实现)的更多相关文章

  1. 结对编程——Java实现黄金分割点游戏

    这是我和队员根据老师要求自创的一个人机黄金分割点游戏.这个小游戏在Windows10 下开发,用Eclipse做开发工具,实现语言是Java. 利用目前自己所学的Java知识实现了一人登录,电脑自行匹 ...

  2. 20175226 2018-2019-2《java程序设计》结对编程-四则运算(第一周-阶段总结)

    结对编程-四则运算(第一周-阶段总结) 需求分析 实现一个四则运算程序,要求: 自动随机生成小学四则运算题目(加,减,乘,除) 支持整数.真分数且支持多项式 能够利用栈的思想,将中缀转换为后缀表达式 ...

  3. 20175305张天钰Java结对编程四则运算(二)

    Java结对编程四则运算(二) 一.题目描述及要求 Git提交粒度不要太粗,建议一个文件/一个类/一个函数/一个功能/一个bug修复都进行提交,不能一天提交一次,更不能一周一次,参考Commit Me ...

  4. 20175305张天钰Java结对编程四则运算

    Java结对编程四则运算 一.题目描述:如何对表达式进行求值运算呢 1.中缀表达式与后缀表达式(娄老师讲解) 中缀表达式就是运算符号在运算数中间的表达式,比如1+2,顾名思义,后缀表达式就是运算符在运 ...

  5. 20175324王陈峤宇 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结

    20175324王陈峤宇 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 这次的结对作业是要求我们利用栈来设计一个计算器. 自动生成四则运算 ...

  6. 20175229许钰玮 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结

    20175229许钰玮 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 自动生成四则运算题目(加.减.乘.除). 既可以用前缀算法(波兰算法 ...

  7. 2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算

    2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算 经过第一阶段的学习,同学们已经熟悉了这门语言基本的用法.在一次又一次对着电脑编写并提交代码,进行练习的时候,有没有觉 ...

  8. 20175312 2018-2019-2 《Java程序设计》结对编程练习_四则运算(第二周:整体性总结)

    20175312 2018-2019-2 <Java程序设计>结对编程练习_四则运算(第二周:整体性总结) 结对对象与其博客链接 20175309 刘雨恒:https://www.cnbl ...

  9. 20175312 2018-2019-2 《Java程序设计》结对编程练习_四则运算(第一周:阶段性总结)

    20175312 2018-2019-2 <Java程序设计>结对编程练习_四则运算(第一周:阶段性总结) 结对对象与其博客链接 20175309 刘雨恒:https://www.cnbl ...

  10. JAVA结对编程--阶段总结

    一.需求分析 1.基本需求 随机生成n道题目 支持整数.分数,支持多运算符 能判断正误,错误时给出正确答案 能计算出正确率 2.扩展需求 处理生成题目并输出到文件 完成题目后从文件读入并判题 支持多语 ...

随机推荐

  1. element-ui更改滚动条颜色

    .find-car ::-webkit-scrollbar-thumb{ background-color: #001f3f; } .find-car ::-webkit-scrollbar-trac ...

  2. 获取BOM标准用量

    Select dbms_aw.eval_number(listagg(' 1' ||                                        sys_connect_by_pat ...

  3. 解决N个人过桥时间最短问题(Java版本)

    [问题描述] n个人要晚上过桥,在任何时候最多两个人一组过桥,每组要有一只手电筒.在这n个人中只有一个手电筒能用,因此要安排以某种往返的方式来返还手电筒,使更多的人可以过桥.   注意:每个人的过桥速 ...

  4. MNIST手写数字识别进阶:多层神经网络及应用(1)

    # 一.载入数据 import tensorflow as tf import numpy as np #导入tensorflow提供的读取MNIST的模块 import tensorflow.exa ...

  5. webapi使用ExceptionFilterAttribute过滤器

    文章 public class ApiExceptionFilterAttribute:ExceptionFilterAttribute { public override void OnExcept ...

  6. 合并K个有序数组-Java

    package com.rao.algorithm; import java.util.Arrays; /** * @author Srao * @className MergeK * @date 2 ...

  7. go 创建切片

    package main import "fmt" func main() { //自动推导类型,同时进行初始化 s1 := [],,,} fmt.Println("s1 ...

  8. JQuerys实现三级省市联动

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. 使用system V实现读者写者问题

    #include <stdio.h> #include <sys/sem.h> #include <sys/ipc.h> #include <string.h ...

  10. Codeforces Round #573 (Div. 2) Tokitsukaze and Mahjong 水题

    B. Tokitsukaze and Mahjong time limit per test1 second memory limit per test256 megabytes Tokitsukaz ...