一 、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. express 将 Router 实例模块化

    为了更好的组织代码,将 Router 实例进行模块化,将 get / post 等快捷方式放在Router上,而不是 App 上,然后将该 Router 作为中间件,use 到 server.js 上 ...

  2. [PHP] PHP PDO与mysql的连接单例防止超时情况处理

    这个数据库类主要处理了单例模式下创建数据库对象时,如果有两次较长时间的间隔去执行sql操作,再次处理会出现连接失败的问题,利用一个cache数组存放pdo对象与时间戳,把两次执行之间的时间进行了比较, ...

  3. golang数据结构和算法之CircularBuffer环形缓冲队列

    慢慢练语法和思路, 想说的都在代码及注释里. CircularBuffer package CircularBuffer const arraySize = 10 type CircularBuffe ...

  4. 2018年蓝桥杯B组C/C++决赛题解

    2018年第九届蓝桥杯B组C/C++决赛题解 点击查看2018年蓝桥杯B组C/C++决赛题目(不含答案) 1.换零钞 ok 枚举 设x表示1元钱的个数,y表示2元钱的个数,z表示5元钱的个数 x+21 ...

  5. Pwnable-flag

    Download : http://pwnable.kr/bin/flag 先下载下来,之后用IDA打开,发现没有什么特别的东西,之后发现是经过UPX压缩过的 xxd flag 先脱壳再说, 之后再将 ...

  6. go 创建切片

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

  7. 【CodeChef EDGEST】Edges in Spanning Trees(树链剖分+树上启发式合并)

    点此看题面 大致题意: 给你两棵\(n\)个点的树,对于第一棵树中的每条边\(e_1\),求存在多少条第二棵树中的边\(e_2\),使得第一棵树删掉\(e_1\)加上\(e_2\).第二棵树删掉\(e ...

  8. Paper | Non-Local ConvLSTM for Video Compression Artifact Reduction

    目录 1. 方法 1.1 框图 1.2 NL流程 1.3 加速版NL 2. 实验 3. 总结 [这是MFQE 2.0的第一篇引用,也是博主学术生涯的第一篇引用.最重要的是,这篇文章确实抓住了MFQE方 ...

  9. Java连载7-变量&数据类型

    一.变量 1.注意点: 在同一个“作用域”中,变量名不能重名,但是变量可以重新赋值. 2.什么是作用域? 答:描述的是变量的有效范围,在范围之内是可以被访问的,只要出了作用域就无法访问(也就是在大括号 ...

  10. cap理论与分布式事务的解决方案

    现在很火的微服务架构所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即一个分布式系统要同时满足一致性(Consistency).可用性(Availablility)和分区容错(Partit ...