码云地址:https://git.oschina.net/ybsnn/four_formula
大题目:完成一个基于控制台的四则运算程序,实现一个自动生成小学四则运算题目的命令行程序
从《构建之法》第一章的 “程序” 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 “软件”。
一、程序设计及实现
a.需求分析
1.四则运算是小学数学计算教学中的难点内容,也是孩子们出错率最高的题型之一。因而设计两个数的四则运算题库,提高孩子们的计算能力以及反应能力。
2.在没有括号的算式里,如果只有加、减法或者只有乘、除法,都要从左往右按顺序计算。
3.整数也能写成分数形式,适用于分数四则运算。
4.虽说有些结果也能用小数形式表示,可是不精确。所以最终结果不管是整数还是分数,我都设计为分数形式。
b.功能设计
1.基本功能
- 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 = 7/24
- 运算符为 +, −, ×, ÷
- 并且要求能处理用户的输入,并判断对错,打分统计正确率
- 要求能处理用户输入的真分数, 如 1/2, 5/12 等
- 使用 -n 参数控制生成题目的个数,例如执行下面命令将生成10个题目
Myapp.exe -n 10
2.扩展功能
对于错误答案的四则算式,输出正确答案
3.高级功能
用户输入可以比较自由,增加撤回功能。
c.设计实现
1.解题思路:
- 随机生成整数或真分数、运算符
- 生成式子,计算并储存参考答案
- 打印输出,用户输入答案
- 比较答案,判断正误。
- 统计答对的题目,计算并输出正确率
2.结构体:
储存分数fraction
typedef struct fraction //分数形式 { int a; int b; }Fraction;
算式formula
typedef struct formula //算式 { Fraction fra[2]; //运算数 int op; //运算符 }Form;
d.代码说明
生成真分数
Fraction createfraction() //产生真分数 { int a,b; int n,op; Fraction fra; do { a=rand()%100 + 1; b=rand()%100 + 1; n=Greatese_divisor(a,b); if(a<b && n==1) //判断真分数 break; }while(1); fra.a=a; fra.b=b; return fra; }
生成式子
Form create() { int op=1,type=1; //默认整数加法运算 int z;Fraction fra[2]; Form form;int i,j; for(i=0;i<2;i++) { type=rand()%2 + 1; switch(type) { case 1:z=rand()%100+1;fra[i].a=z;fra[i].b=1;break; //产生整数 case 2:fra[i]=createfraction();break; //产生真分数 } form.fra[i]=fra[i]; } op=rand()%4+1; //随机产生运算符 form.op=op; return form; }
求两数的最大公约数
int Greatese_divisor(int x,int y) //求两数的最大公约数 { int r; r=x%y; while(r!=0) { x=y; y=r; r=x%y; } return y; }
计算算式结果
Fraction count(Form form) //计算算式结果 { int l,g;int a1,a2,a,b;Fraction fra; g=Greatese_divisor(form.fra[0].b,form.fra[1].b); l=form.fra[0].b*form.fra[1].b/g; a1=form.fra[0].a*l/form.fra[0].b; a2=form.fra[1].a*l/form.fra[1].b; switch(form.op) { case 1:a=a1 + a2;b=l;break; case 2:a=a1 - a2;b=l;break; case 3:b=form.fra[0].b*form.fra[1].b;a=form.fra[0].a*form.fra[1].a;break; case 4:b=form.fra[0].b*form.fra[1].a;a=form.fra[0].a*form.fra[1].b;break; } fra.a=a; fra.b=b; fra=simplity(fra); return fra; }
打印题目
void printForm(Form form) //打印题目 { if(form.fra[0].b==1) printf("%d ",form.fra[0].a); else printf("%d/%d ",form.fra[0].a,form.fra[0].b); switch(form.op) { case 1:printf("+");break; case 2:printf("-");break; case 3:printf("×");break; case 4:printf("÷");break; } if(form.fra[1].b==1) printf(" %d =",form.fra[1].a); else printf(" %d/%d =",form.fra[1].a,form.fra[1].b); }
判断答题正误
bool check_answer(Fraction fra) { int a,b; scanf("%d",&a); scanf("%d",&b); if(a==fra.a && b==fra.b) { printf(" bingo~~~ "); return true; } else { printf(" sorry---"); printf(" 答案:%d/%d ",fra.a,fra.b); return false; } return true; }
e.测试运行
二、展示PSP
PSP2.1 | Personal Software Process Stages | Time (%) Senior Student | Time (%) |
Planning | 计划 | 30min | 35min |
· Estimate | 估计这个任务需要多少时间 | 6h | 8h |
Development | 开发 | -- | -- |
· Analysis | 需求分析 (包括学习新技术) | 10min | 8min |
· Design Spec | 生成设计文档 | 15min | 20min |
· Design Review | 设计复审 | -- | -- |
· Coding Standard | 代码规范 | 10min | 15min |
· Design | 具体设计 | 30min | 25min |
· Coding | 具体编码 | 4h | 6.5h |
· Code Review | 代码复审 | 1h | 45min |
· Test | 测试(自我测试,修改代码,提交修改) | 1h | 1h20min |
Reporting | 报告 | 30min | 45min |
· | 测试报告 | -- | -- |
· | 计算工作量 | 5min | 8min |
· | 并提出过程改进计划 | 30min | -- |
三、小结
1.这次题目虽说简单,还是花费了太多的时间了。归结来,自己在寒假期间不怎么编程,以至于过于生疏,把很多语法都忘了。今后我要勤加练习了。
2.这次程序写的比较渣啦,异常都没有处理,而且代码可扩展性不高。如果要混合运算的话,太多地方要修改了。