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

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

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

    之前在编写oracle的sql语句时遇到这个问题,这里做个记录 问题描述:ORA-00937: 不是单组分组函数 问题原因:select语句中又在查询某一列的值,其中还有聚合函数 原先本人编写SQL是 ...

  2. mysql 添加时间自动添加更新时间自动更新

    在数据库使用中经常使用到时间字段.常用的有创建时间和更新时间.然而在使用中想要创建时间在创建的时候自动设置为当前时间,更新时间在更新时自动更新为当前时间. 创建表 stu CREATE TABLE ` ...

  3. RockBrain USB Server外设虚拟化高可用解决方案(银企直联虚拟化解决方案)

    技术指标: 单.双千兆网络界面(支持链路冗余与链路热备.支持双网口均衡负载) 原生USB2.0接口(USB2.0与USB3.0接口均对所有USB版本设备兼容,支持混插) 技术优势: RockBrain ...

  4. UE4 移动物体的几种方法

    转自:https://dawnarc.com/2016/06/ue4%E7%A7%BB%E5%8A%A8%E7%89%A9%E4%BD%93%E7%9A%84%E5%87%A0%E7%A7%8D%E6 ...

  5. Lock Free (无锁并发)

    CAS( compare and swap) 原子操作,保证了如果需要更新的地址没有被其他进程(线程)改动过,那么它可以安全的写入.而这也是我们对于某个数据或者数据结构加锁要保护的内容,保证读写的一致 ...

  6. git第一次上传push失败解决

    第一次上传有可能会遇到push失败的情况,那是因为跟SVN一样,github上有一个README.md 文件没有下载下来 .我们得先 git pull --rebase origin master   ...

  7. Scala 安装 Scala for Eclipse安装及运行hello word

    Scala下载安装地址:https://www.scala-lang.org/download/ .windows版本的安装包是scala-2.12.8.msi.直接滑动到网页最下面,下载对应的系统的 ...

  8. DS DI ES SI等等

    DS is called data segment register. It points to the segment of the data used by the running program ...

  9. js拼接url以及为html某标签属性赋值

    记录 js拼接url 比如有些时候我们需要为某按钮实现跳转,可以利用下面的方式做到: function ReturnIndex() { var rex = RegExp("tools&quo ...

  10. 「UR#5」怎样跑得更快

    「UR#5」怎样跑得更快 膜这个您就会了 下面是复读机mangoyang 我们要求 \[ \sum_{j=1}^n \gcd(i,j)^{c-d} j^d x_j=\frac{b_i}{i^d} \] ...