任务:实现一个自动生成小学四则运算题目的命令行程序。
1)PSP表格记录
PSP2.1 |
Personal Software Process Stage |
估计 |
实际 |
Planning |
计划 |
||
· Estimate |
· 估计这个任务需要多少时间 |
21h |
29h |
Development |
开发 |
||
· Analysi |
· 需求分析 (包括学习新技术) |
1h |
3h |
· Design Spec |
· 生成设计文档 |
0.5h |
0.5 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
0 |
0 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
0 |
0 |
· Desig |
· 具体设计 |
1h |
1h |
· Coding |
· 具体编码 |
15h |
20h |
· Code Review |
· 代码复审 |
0 |
0 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
2h |
3h |
Reporting |
报告 |
||
· Test Report |
· 测试报告 |
0.5h |
0.5h |
· Size Measurement |
· 计算工作量 |
0.5h |
0.5h |
· Postmortem & Process Improvement Pla |
· 事后总结, 并提出过程改进计划 |
0.5h |
0.5h |
合计 |
21h |
29h |
PSP2.1
Personal Software Process Stage
估计
实际
Planning
计划
· Estimate
· 估计这个任务需要多少时间
21h
29h
Development
开发
· Analysi
· 需求分析 (包括学习新技术)
1h
3h
· Design Spec
· 生成设计文档
0.5h
0.5
· Design Review
· 设计复审 (和同事审核设计文档)
· Coding Standard
· 代码规范 (为目前的开发制定合适的规范)
· Desig
· 具体设计
1h
1h
· Coding
· 具体编码
15h
20h
· Code Review
· 代码复审
· Test
· 测试(自我测试,修改代码,提交修改)
2h
3h
Reporting
报告
· Test Report
· 测试报告
0.5h
0.5h
· Size Measurement
· 计算工作量
0.5h
0.5h
· Postmortem & Process Improvement Pla
· 事后总结, 并提出过程改进计划
0.5h
0.5h
合计
21h
29h
2)编码过程(主要是编码过程中遇到的问题所做的处理)
1. 对带分数的表达式的处理。
查阅相关资料时发现可以使用逆波兰表达式来处理数学表达式。其原理是将人们习惯的的中缀表达式转化成后缀表达式。查阅了相关代码,并在此基础上修改成可以支持分数的函数。其主要思想就是将一个整数化成n/1的形式,再进行相关的计算。我设计了如下的一个类:
View Code
2. 快速生成不相同的随机数
因为程序要求可以生成一万个代码,在要求效率的基础上,肯定不能用简单的使用当前系统时间作为随机数的种子。否则在短时间内会生成大量一样的随机数。也不能用Sleep的方式,否则会降低程序的效率。查阅相关资料,问题得以解决。
3. 产生不重复的表达式
因为老师对需求做了些简化,我便想到了一个比较投机的办法。就是将中缀表达式化成后缀表达式,只要一个加号和乘号之前的两个数字位置进行调换,并存入表中,再用Contains的方法进行判断。
举个例子:
对于1+2+3的中缀形式,可以化为1 2 + 3 +的后缀形式,只要将1和2调换一个位置,变为2 1 + 3 + 只要以后的生成表达式和上面俩个式子不同,就不会有重复。
同理的对于1+(2+3)的中缀形式是1 2 3 + +。调换后为1 3 2 + +。
代码如下:
View Code
3)程序优化
对于生成10000个算式,没优化是这样的:
程序将近执行了3分钟
可以看出Simplification这个函数占用的时间最长。这个函数是用来将一个分数化简成最简形式。一开始的思路是从分子逐个向下做减一的循环。当分子和分母同时可以将这个数整除,即为最大公约数。最后同时除以这个公约数即为最
后来发现可以使用辗转相除法化来找公约数,来提高整个程序的效率,相对应的getChild函数也不会调用那么多次的。
同理在ToString函数中会将一个假分数化成真分数,一开始也是用循环累加的方式。后来发现其系数可以是原分子除以分母的结果,分子可以是原分子对分母的求余。遂改进。
这就是优化过后的结果。可以发现程序的效率大大的提升了。
4)测试
输入-n 10000 -r 10000 测试是否能生成一万个算式。
输入-e -a 测试是否能判断自动生成的文件
对文件进行修改,判断是否能正确判断正误。
将9988号题目的结果改为1。将9999的结果直接删除。
程序均能正确判断。
并且经过人工肉眼扫描是否有假分数和负数的结果,和包含假分数的算术。均为扫描到。