结对编程(-java-实现)
一 、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-实现)的更多相关文章
- 结对编程——Java实现黄金分割点游戏
这是我和队员根据老师要求自创的一个人机黄金分割点游戏.这个小游戏在Windows10 下开发,用Eclipse做开发工具,实现语言是Java. 利用目前自己所学的Java知识实现了一人登录,电脑自行匹 ...
- 20175226 2018-2019-2《java程序设计》结对编程-四则运算(第一周-阶段总结)
结对编程-四则运算(第一周-阶段总结) 需求分析 实现一个四则运算程序,要求: 自动随机生成小学四则运算题目(加,减,乘,除) 支持整数.真分数且支持多项式 能够利用栈的思想,将中缀转换为后缀表达式 ...
- 20175305张天钰Java结对编程四则运算(二)
Java结对编程四则运算(二) 一.题目描述及要求 Git提交粒度不要太粗,建议一个文件/一个类/一个函数/一个功能/一个bug修复都进行提交,不能一天提交一次,更不能一周一次,参考Commit Me ...
- 20175305张天钰Java结对编程四则运算
Java结对编程四则运算 一.题目描述:如何对表达式进行求值运算呢 1.中缀表达式与后缀表达式(娄老师讲解) 中缀表达式就是运算符号在运算数中间的表达式,比如1+2,顾名思义,后缀表达式就是运算符在运 ...
- 20175324王陈峤宇 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结
20175324王陈峤宇 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 这次的结对作业是要求我们利用栈来设计一个计算器. 自动生成四则运算 ...
- 20175229许钰玮 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结
20175229许钰玮 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 自动生成四则运算题目(加.减.乘.除). 既可以用前缀算法(波兰算法 ...
- 2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算
2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算 经过第一阶段的学习,同学们已经熟悉了这门语言基本的用法.在一次又一次对着电脑编写并提交代码,进行练习的时候,有没有觉 ...
- 20175312 2018-2019-2 《Java程序设计》结对编程练习_四则运算(第二周:整体性总结)
20175312 2018-2019-2 <Java程序设计>结对编程练习_四则运算(第二周:整体性总结) 结对对象与其博客链接 20175309 刘雨恒:https://www.cnbl ...
- 20175312 2018-2019-2 《Java程序设计》结对编程练习_四则运算(第一周:阶段性总结)
20175312 2018-2019-2 <Java程序设计>结对编程练习_四则运算(第一周:阶段性总结) 结对对象与其博客链接 20175309 刘雨恒:https://www.cnbl ...
- JAVA结对编程--阶段总结
一.需求分析 1.基本需求 随机生成n道题目 支持整数.分数,支持多运算符 能判断正误,错误时给出正确答案 能计算出正确率 2.扩展需求 处理生成题目并输出到文件 完成题目后从文件读入并判题 支持多语 ...
随机推荐
- element-ui更改滚动条颜色
.find-car ::-webkit-scrollbar-thumb{ background-color: #001f3f; } .find-car ::-webkit-scrollbar-trac ...
- 获取BOM标准用量
Select dbms_aw.eval_number(listagg(' 1' || sys_connect_by_pat ...
- 解决N个人过桥时间最短问题(Java版本)
[问题描述] n个人要晚上过桥,在任何时候最多两个人一组过桥,每组要有一只手电筒.在这n个人中只有一个手电筒能用,因此要安排以某种往返的方式来返还手电筒,使更多的人可以过桥. 注意:每个人的过桥速 ...
- MNIST手写数字识别进阶:多层神经网络及应用(1)
# 一.载入数据 import tensorflow as tf import numpy as np #导入tensorflow提供的读取MNIST的模块 import tensorflow.exa ...
- webapi使用ExceptionFilterAttribute过滤器
文章 public class ApiExceptionFilterAttribute:ExceptionFilterAttribute { public override void OnExcept ...
- 合并K个有序数组-Java
package com.rao.algorithm; import java.util.Arrays; /** * @author Srao * @className MergeK * @date 2 ...
- go 创建切片
package main import "fmt" func main() { //自动推导类型,同时进行初始化 s1 := [],,,} fmt.Println("s1 ...
- JQuerys实现三级省市联动
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 使用system V实现读者写者问题
#include <stdio.h> #include <sys/sem.h> #include <sys/ipc.h> #include <string.h ...
- Codeforces Round #573 (Div. 2) Tokitsukaze and Mahjong 水题
B. Tokitsukaze and Mahjong time limit per test1 second memory limit per test256 megabytes Tokitsukaz ...