结对项目

作业要求

3121005275 杨钢涛
3121005279 张宏
github项目地址

这个作业属于哪个课程 软件工程
这个作业要求在哪里 结对项目
这个作业的目标 完成结对项目,培养协作能力

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 40 30
Estimate 估计这个任务需要多少时间 200 250
Development 开发 220 300
Analysis 需求分析 (包括学习新技术) 60 90
Design Spec 生成设计文档 40 50
Design Review 设计复审 30 40
Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 30
Design 具体设计 20 25
Coding 具体编码 200 190
Code Review 代码复审 20 20
Test 测试(自我测试,修改代码,提交修改) 30 20
Reporting 报告 20 20
Test Repor 测试报告 15 15
Size Measurement 计算工作量 15 20
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 20 25
合计 960 1125

1题目:实现一个自动生成小学四则运算题目的命令行程序(也可以用图像界面,具有相似功能)。

2说明:

自然数:0, 1, 2, …。

真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
运算符:+, −, ×, ÷。
括号:(, )。
等号:=。
分隔符:空格(用于四则运算符和等号前后)。
算术表达式:
e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),

其中e, e1和e2为表达式,n为自然数或真分数。

四则运算题目:e = ,其中e为算术表达式。

3需求:

使用 -n 参数控制生成题目的个数,例如

Myapp.exe -n 10

将生成10个题目。

使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如

Myapp.exe -r 10

将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。

生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2。
生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。
每道题目中出现的运算符个数不超过3个。
程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。
生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:

四则运算题目1
四则运算题目2
……

其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。

在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:

答案1
答案2

特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。

程序应能支持一万道题目的生成。
程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:

Myapp.exe -e .txt -a .txt

统计结果输出到文件Grade.txt,格式如下:

Correct: 5 (1, 3, 5, 7, 9)

Wrong: 5 (2, 4, 6, 8, 10)

其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目都是按照顺序编号的符合规范的题目。

效能分析


从图中可以看出CPU在生成算式时达到峰值,运用最多的是FormExpression函数中对string的调用,所以项目中byte[]内存占大多数
程序中消耗最大的函数:
String FormExpression(int size , int operatenum) { Random r = new Random(); String[] operate = {"+","-","×","÷"}; StringBuffer str = new StringBuffer(); StringBuffer strnew = new StringBuffer(); int num; int numerator; int denominator; String oper; Fenshu fenshu; int divcount = 0; String[] numlist = new String[operatenum+1]; String[] operlist = new String[operatenum]; for(int i=0;i<operatenum;i++) { oper=operate[r.nextInt(4)]; operlist[i]=oper; if(oper.equals("÷")) { divcount++; } } for(int i=0;i<operatenum+1;i++) { if(divcount==0) { num=r.nextInt(size); numerator = r.nextInt(size); denominator = r.nextInt(size); }else { num=r.nextInt(size)+1; numerator = r.nextInt(size)+1; denominator = r.nextInt(size)+1; } if(denominator!=0&&numerator<=denominator) { fenshu = new Fenshu(numerator,denominator); }else { fenshu = new Fenshu(denominator, numerator); } numlist[i]=randominput(num, fenshu); } for(int i=0;i<2*operatenum+1;i++) { if(i%2==0) { str.append(numlist[i/2]+" "); } if(i%2!=0) { str.append(operlist[(i-1)/2]+" "); } } str.append("="+" "); String[] judge = str.toString().split(" "); for(int i=1;i<judge.length-1;i+=2) { if(judge[i].equals("-")) { Fenshu fs = new Fenshu(); Expression ex = new Expression(); StringBuffer font = new StringBuffer(); StringBuffer back = new StringBuffer(); StringBuffer newstr = new StringBuffer(); for(int k=0;k<i;k++) { font.append(judge[k]+" "); } for(int k=i+1;k<judge.length-1;k++) { back.append(judge[k]+" "); } Fenshu fontfs = ex.count(font.toString()); Fenshu backfs = ex.count(back.toString()); String fontstr = fontfs.numerator+"/"+fontfs.denominator; String backstr = backfs.numerator+"/"+backfs.denominator; if(fs.compute(fontstr, backstr)) { newstr.append(back.toString()+"- "+font.toString()+"= "); String[] newjudge = newstr.toString().split(" "); for(int k=0;k<newjudge.length;k++) { judge[k]=newjudge[k]; } } } } for(int i=0;i<judge.length;i++) { strnew.append(judge[i]+" "); } return strnew.toString(); }

设计实现过程

共有六个类

Fenshu:定义分数结构,并实现分数的加减乘除,其中包括了对两部分表达式的大小比较函数compute
FormExpression:生成表达式
Expression:计算结果
build:实现命令行题目数量和数值大小输入和输出表达式和答案到TXT文件
CorrectandWrong:命令行输入试卷文件和答案文件,判断对错并统计
jisuanji:主函数只用while持续调用build类和CorrectandWrong类
程序流程图:

代码说明

随机出现算式运算符

一般计算式转换为后缀表达式

后缀表达式计算

测试运行

生成算式

结果校验

Exercises.txt文件内容

Answers.txt文件内容

项目小结

在这次的结对编程中,多跟他人交流沟通会有很大的收获。在这过程中,我和结对伙伴就生成表达式过程中该如何存储,如果结果为负数在生成过程中该如何实现不生成负数结果的表达式,分数的实现和计算,括号的优先运算,后缀表达式的实现进行了较深入的探讨,从而收获了很多新的知识。

posted @ 2023-09-26 15:21  计科4杨钢涛  阅读(42)  评论(0编辑  收藏  举报