个人作业1——四则运算题目生成程序(基于控制台)
coding : https://git.oschina.net/linjunp/project1-arithmetic
题目要求:
从《构建之法》第一章的 “程序” 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 “软件”,满足以下需求:
- 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 = 7/24
- 运算符为 +, −, ×, ÷
- 并且要求能处理用户的输入,并判断对错,打分统计正确率。
- 要求能处理用户输入的真分数, 如 1/2, 5/12 等
- 使用 -n 参数控制生成题目的个数,例如执行下面命令将生成10个题目
Myapp.exe -n 10
a.需求分析:
这个题目的难点在于分数的运算,分数与分数,分数和整数的运算需要对结果进行约分,而且分数中的“/”的存在决定了对分数的类型为string。
b.功能设计:
程序中,用户可以自己选择题目的数量,若用户输入的答案错误,程序会显示正确答案;
c.设计实现:
在这个程序中,程序需要自己随机生成一个式子,运算符有“+,-,&,/”,运算数有分数和整数,而整数和整数,整数和分数,分数和分数的计算的步骤不相同;
所以针对整数和整数,整数和分数,分数和分数的运算类型设计了三种函数:oper1,oper2,oper3;函数的返回类型都为string类型的rst(计算结果);
在main()中使用rand()随机生成一个operation(运算符号),一种operand(若operand=1,2为整数和整数运算,若operand=3,为整数和分数运算,若operand=4,为分数和分数运算);
在while 循环中,针对每次的operand的情况,可以为oper函数传递参数,通过函数的返回值和用户输入的比较,若相同则正确,输出正确率;不相同则错误,同时输出正确答案和正确率;
d.代码说明:
1 string ReducofFrac(int numerator ,int denominator) //Reduction of a fraction
2 {
3 string rst;
4 for(int i = 2 ; numerator >= i ; i++ )
5 if((numerator)%i == 0 && denominator%i == 0)
6 {
7 numerator/=i;
8 denominator/=i;
9 i--;
10 }
11 return rst = to_string(numerator)+'/'+to_string(denominator);
12 }
1 string arithmetic1(char op,int integer,int numerator,int denominator)//整数和分数的运算 2 { 3 string rst; 4 int temp1; 5 if(op=='+') 6 { 7 return rst=to_string(integer*denominator+numerator)+'/'+to_string(denominator); 8 } 9 if(op=='-') 10 { 11 return rst=to_string(integer*denominator-numerator)+'/'+to_string(denominator); 12 } 13 if(op=='*') 14 { 15 return ReducofFrac(integer*numerator,denominator); 16 } 17 if(op=='/') 18 { 19 return ReducofFrac(integer*denominator,numerator); 20 } 21 }
1 string arithmetic2(char op,int integer1,int integer2)//整数和整数的运算 2 { 3 int temp1; 4 string rst; 5 if(op=='+') 6 { 7 return rst = to_string(integer1 + integer2); 8 } 9 if(op=='-') 10 { 11 if(integer1 <= integer2) 12 { 13 temp1 = integer1; 14 integer1 = integer2+1; 15 integer2 = temp1; 16 } 17 return rst = to_string(integer1 - integer2); 18 } 19 if(op=='*') 20 { 21 return rst = to_string(integer1 * integer2); 22 } 23 if(op=='/') 24 { 25 return ReducofFrac(integer1,integer2); 26 } 27 }
1 string arithmetic3(char op,int numerator1,int denominator1,int numerator2,int denominator2)//分数和分数的运算 2 { 3 string rst; 4 int temp1,temp2; 5 if(op=='+') 6 { 7 temp1 = numerator1 * denominator2 + numerator2 * denominator1; 8 temp2 = denominator1 * denominator2; 9 return ReducofFrac(temp1,temp2); 10 } 11 if(op=='-') 12 { 13 temp1 = numerator1 * denominator2 - numerator2 * denominator1; 14 temp2 = denominator1 * denominator2; 15 return ReducofFrac(temp1,temp2); 16 } 17 if(op=='*') 18 { 19 temp1 = numerator1 * numerator2; 20 temp2 = denominator1 * denominator2; 21 return ReducofFrac(temp1,temp2); 22 } 23 if(op=='/') 24 { 25 temp1 = numerator1 * denominator2; 26 temp2 = denominator1 * numerator2; 27 return ReducofFrac(temp1,temp2); 28 } 29 }
e.测试运行:
2.展示PSP
PSP2.1 |
Personal Software Process Stages |
计划(min) |
实际(min) |
Planning |
计划 |
20 |
25 |
Development |
开发 |
40 |
60 |
Analysis |
需求分析 (包括学习新技术) |
10 |
20 |
Coding Standard |
代码规范 |
10 |
20 |
Design |
具体设计 |
10 |
20 |
Coding |
具体编码 |
40 |
60 |
Test |
测试(自我测试,修改代码,提交修改) |
10 |
10 |
Reporting |
报告 |
10 |
10 |
3.总结
编程过程遇到最大的困难就是:一开始,使用if()对四种运算符和4种运算情况进行判断,但是这样将有4*4=16种情况进行判断,而且每种情况都还要判断正确,显得非常臃肿和不美观。
所以写了oper1,oper2,oper3函数,不仅结构明朗,而且代码量少了很多。
虽然问题解决了,但是还是浪费了半天的时间,最主要的问题是在设计阶段没有明确想到细节上,以为思路差不多就可以成功。
所以,编程虽然重要,但是其他环节也不容忽视。
4.修改
函数oper1,oper2,oper3修改为arithmetic1,arithmetic2,arithmetic3;
添加了ReducofFrac函数用于分数的约分,在算法函数中嵌套使用,减少冗杂;
修改了to_string函数,解决了参数为负数或者0的答案不显示;