作业要求来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2166
github仓库:https://github.com/pbygakki/testone
一、题目要求:
像《构建之法》的人物阿超那样,写一个能自动生成小学四则运算题目的命令行 “软件”。
具体要求:任何编程语言都可以,命令行程序接受一个数字输入,然后输出相应数目的四则运算题目和答案。例如输入数字是 30, 那就输出 30 道题目和答案。 运算式子必须至少有两个运算符,运算数字是在 100 之内的正整数,答案不能是负数。 如:如:23 - 3 * 4 = 11。
扩展要求:
1) 要求能出和真分数 (二分之一, 十二分之五,等)相关的练习题。
2) 并且要求能处理用户的输入,并判断对错,打分统计。 要求能处理用户输入的真分数, 如 1/2, 5/12 等。初步拟定要实现的功能后,估计一下自己需要花多长时间。编程过程中记录自己实际用了多长时间。然后和同学们比较一下各自程序的功能、实现方法的异同等等。写博客纪录自己实现的过程和思路。
二、个人软件过程耗时估计与统计表
PSP2.1 | Personal Software Process Stages | Time Senior Student(h) | Time(h) |
Planning | 计划 | 1 | 1 |
Estimate | 估计这个任务需要多少时间 | 3 | 5 |
Development | 开发 | 10 | 20 |
Analysis | 需求分析 (包括学习新技术) | 5 | 4 |
Design Spec | 生成设计文档 | 1 | 1 |
Design Review | 设计复审 | 3 | 6 |
Coding Standard | 代码规范 | 1 | 2 |
Design | 具体设计 | 2 | 2 |
Coding | 具体编码 | 2 | 1 |
Code Review | 代码复审 | 1 | 3 |
Test | 测试(自我测试,修改代码,提交修改) | 1 | 2 |
Reporting | 报告 | 1 | 1 |
测试报告 | 1 | 1 | |
计算工作量 | 1 | 1 | |
并提出过程改进计划 | 1 | 1 |
三、代码实现
- 首先让用户输入题目的数目,根据用户输入的题目一条一条生成。
- 用Random方法随机生成1到100的正整数,然后通过调用两个运算符将三个随机数进行运算。
- 通过getResult函数得到的数值和自己输入的答案作比较。答案正确,返回正确题目书1,否则0
- 计算测试的正确率,按照总分100的百分比才算出最终成绩。
代码:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <iostream.h> //主要函数: char getSignal(); //获取随机运算符函数 int random(double,double); //获取随机数函数 int getResult(int,int,int,char,char); //结果计算函数 int takeTest(); //题目生成函数 //主函数 void main() { int n,a,right=0; double percent;//正确率 float score;//分数 printf("Please enter the number of the test:");//输入你要生成的题目数量 scanf("%d",&n); for(int i=0;i<n;i++) { a=takeTest(); right=right+a; } printf("You finish all test!\n"); printf("The number of right:%d\n",right); percent=((double)right*100.00)/(double)n; score=percent; printf("The percent of right:%0.2f %%\n",percent); printf("The score of right:%0.2f %\n",score); } //获取随机运算符函数: char getSignal() { char signal[4]={'+','-','*','/'}; return signal[rand()%4]; } //获取随机数函数: int random(double start, double end) { return (int)(start+(end-start)*rand()/(RAND_MAX+ 1.0)); } //结果计算函数: int getResult(int num1,int num2,int num3,char signal,char signal2) { int res; switch(signal) { case '+': //第一个运算符为加号的运算 switch(signal2){ case '+': res=num1+num2+num3;break; case '-': res=num1+num2-num3;break; case '*': res=num1+num2*num3;break; case '/': res=num1+num2/num3;break; } break; case '-': //第一个运算符为减号的运算 switch(signal2){ case '+': res=num1-num2+num3;break; case '-': res=num1-num2-num3;break; case '*': res=num1-num2*num3;break; case '/': res=num1-num2/num3;break; } break; case '*': //第一个运算符为乘号的运算 switch(signal2){ case '+': res=num1*num2+num3;break; case '-': res=num1*num2-num3;break; case '*': res=num1*num2*num3;break; case '/': res=num1*num2/num3;break; } break; case '/': //第一个运算符为除号的运算 switch(signal2){ case '+': res=num1/num2+num3;break; case '-': res=num1/num2-num3;break; case '*': res=num1/num2*num3;break; case '/': res=num1/num2/num3;break; } break; default: printf("运算符错误!\n"); } return res; } //题目生成函数: int takeTest() { int get; int num1,num2,num3,a; char signal,signal2; srand((unsigned)time(NULL));//随机数种子 signal2=getSignal();//两个运算符的调用函数 signal=getSignal(); num1=random(1,100); num2=random(1,100); num3=random(1,100); printf("%d%c%d%c%d=",num1,signal,num2,signal2,num3); scanf("%d",&get); fflush(stdin); //清空输入缓冲区 if(getResult(num1,num2,num3,signal,signal2)==get)//运算结果和自己输入的结果作比较 { printf("You're right!\n"); a=1; } else { printf("It's wrong!\n"); printf("The right answer is: %d\n",getResult(num1,num2,num3,signal,signal2)); a=0; } return a; }
结果截图:
四、遇到的问题及如何解决的
遇到的问题:1、在调用两个运算符时用上了 srand((unsigned)time(NULL));这个方法,然后我把它放到了获取随机运算符函数中,然后就会出现两个运算符相同
2、拓展问题中的实现真分数功能不能实现,构建代码想着把整数先写出来,分数的因为不会如何定义,想过把两个整数一个运算符当成一个字符串,但是字符串如何运算这是个很大的难点,所以想不出。
3、对于c语言只会一些基本的语句,在实现过程中非常不严谨,容错率也很低,所以导致在写代码开发的时候还是用了不少的时间,至于更高层次的分数,我只能理解最大公约数和最小公倍数的部分。
如何解决:1、把这个产生随机数种子的方法删掉,因为这个是根据电脑时间来随机生成的一个随机数,对于同一时间生成的随机数是一样的,所以才会造成两个运算符相同。