一.github项目地址:https://github.com/HLyxd/my-app1
二.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 50 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 40 | 40 |
Development | 开发 | 1250 | 1320 |
· Analysis | · 需求分析 | 120 | 120 |
· Design Spec | · 生成设计文档 | 60 | 80 |
· Design Review | · 设计复审 | 50 | 80 |
· Coding Standard | · 代码规范 | 60 | 60 |
· Design | · 具体设计 | 120 | 110 |
· Coding | · 具体编码 | 850 | 950 |
· Code Review | · 代码复审 | 70 | 90 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | 120 | 120 |
· Test Report | · 测试报告 | 50 | 50 |
· Size Measurement | · 计算工作量 | 40 | 40 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 40 | 50 |
合计 | 2930 | 3290 |
三.效能分析
本次作业因为我们两人的编程能力都不是那么强,所以很多地方的设计上都不是那么简洁,效能分析也完成得不是那么好,有粗略估计一下每次生成题目的时间都在1到2秒,当然,这是在生成的题目并不是那么多的情况,当输入10000的时候,差不多花了九到十秒左右。总体上效能分析我们这个板块做得不不好。
四.解题思路分析
首先拿到题目的时候,在还没组队的时候我们分别有对题目做出自己的见解和解题思路,所以当我们组队的时候我们有先做讨论,各自提出对题目各个要求的自己想法,我们对各个要求的解决方案都有大致想到,有实际上的编程却有一部分没能实现,这一点是受限于我们两人的编程能力不太强。题目是随机生成四则运算,首先我们就是设置一个随机数,这个随机数的取值范围由1到2(因为此次我们实现的顶多为两个运算符),然后再用switch语句根据生成的值转入到对应的运算符数量函数,加减乘除号的随机生成运用了rand函数来随机生成一个1到4的变量,分别对应加号,减号,乘号,除号,在这里当运算符为除号的时候我们采用了辗转相除法,写一个gcd函数来求出两个数的最大公约数,这样来实现输出分数的要求,生成答案和试题文件的话,我们则是通过先定义两个文件指针,指向相对应要写入的文件(Answer.txt和Exercise.txt),然后生成文件并打开文件,通过fprinft将生成的题目和答案写入到相应的文件。
五.代码说明
operationone函数是当运算符为一个时候的情况下,通过随机生成的运算符类型(一到四分别对应加减乘除),然后转入到相对应的情况
int operationone(int numb1,int numb2,int max,int i) //不一定是整型函数
{
int gcd(int numb1,int numb2);
int temp;//中间值
int result;
op1=rand()%4+1; //op1的生成值为1到4,分别对应加法,减法,乘法,除法
fb=fopen("Exercises.txt","a");
fp=fopen("Answers.txt","a");//打开文件
switch(op1){
case 1: //op1为1的时候,执行加法操作
result=numb1+numb2;
fprintf(fp,"题目%d:%d+%d=%d\n",i,numb1,numb2,result); //写入文件
fclose(fp); //关闭文件
fprintf(fb,"题目%d:%d+%d=\n",i,numb1,numb2);
fclose(fb);
break;
case 2 : //op1为2的时候,执行减法操作;
if(numb1<numb2) //为保证结果不为零,当出现生成的被减数比减数小,进行两者值的交换
{
temp=numb1;
numb2=numb1;
numb1=temp;
}
result=numb1-numb2;
fprintf(fp,"题目%d:%d-%d = %d\n",i,numb1,numb2,result);
fclose(fp);
fprintf(fb,"题目%d:%d-%d = \n",i,numb1,numb2);
fclose(fb);
break;
case 3 : //op1为3的时候,执行乘法操作;
result=numb1*numb2;
fprintf(fp,"题目%d:%d*%d = %d\n",i,numb1,numb2,result);
fclose(fp);
fprintf(fb,"题目%d:%d*%d = \n",i,numb1,numb2);
fclose(fb);
break;
case 4 : //op1为4的时候,执行除法操作;
if(numb2==0)
numb2=rand()%max+1;
temp=gcd(numb1,numb2);
fprintf(fp,"题目%d:%d/%d = %d/%d\n",i,numb1,numb2,numb1/temp,numb2/temp);
fclose(fp);
fprintf(fb,"题目%d:%d/%d = \n",i,numb1,numb2);
fclose(fb);
break;
default:printf("ERROR\n");
}
return 0;
}
知识兔
gcd辗转相除法
int gcd(int numb1,int numb2)//辗转相除法
{
if(numb2==0) return numb1;
return gcd(numb2,numb1%numb2);
}
知识兔运算符为两个的情况下:
int operationtwo(int numb1,int numb2,int numb3,int max)
{
int gcd(int numb1,int numb2);
int result, result1,temp,temp1;
op1=rand()%4+1;
op2=rand()%4+1; //op1,op2的生成值为1到4,分别对应加法,减法,乘法,除法
fp=fopen("Answers.txt","a");
fb=fopen("Exercises.txt","a");
switch(op1){
case 1 :
switch(op2){
case 1 : //op1,op2均为加法的情况
result1=numb1+numb2;
result=result1+numb3;
fprintf(fp,"题目%d:%d+%d+%d%=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d+%d+%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 2 : //op1为加法,op2为减法的情况
result1=numb1+numb2;
if(result1<numb3)
{
temp=numb3;
numb3=numb2;
numb2=temp;
}
result=numb1+numb2-numb3;
fprintf(fp,"题目%d:%d+%d-%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d+%d-%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 3 : //op1为加法,op2为乘法的情况
result1=numb2*numb3;
result=numb1+result1;
fprintf(fp,"题目%d:%d+%d*%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d+%d*%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 4 : //op1为加法,op2为除法的情况
if(numb3==0)
{
numb3=rand()%max+1;
}
temp=gcd(numb2,numb3);
fprintf(fp,"题目%d:%d+%d/%d=%d'%d/%d\n",i,numb1,numb2,numb3,numb1,numb2/temp,numb3/temp);
fclose(fp);
fprintf(fb,"题目%d:%d+%d/%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
default:printf("ERROR\n");
}
break;
case 2 :
switch(op2){
case 1 : //op1为减法,op2为加法的情况
if(numb1<numb2) //为保证结果不为零,当出现生成的被减数比减数小,进行两者值的交换
{
temp=numb1;
numb2=numb1;
numb1=temp;
}
result=numb1-numb2+numb3;
fprintf(fp,"题目%d:%d-%d+%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d-%d+%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 2 : //op1为减法,op2为减法的情况
do{
numb1=rand()%max;
numb2=rand()%max;
numb3=rand()%max;
}while((numb1-numb2-numb3)<=0);
result=numb1-numb2-numb3;
fprintf(fp,"题目%d:%d-%d-%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d-%d-%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 3 : //op1为减法,op2为乘法的情况
do{
numb1=rand()%max;
numb2=rand()%max;
numb3=rand()%max;
}while((numb1-numb2*numb3)<0);
result=numb1-numb2*numb3;
fprintf(fp,"题目%d:%d-%d*%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d-%d*%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 4 : //op1为减法,op2为除法的情况
do{
numb1=rand()%max;
numb2=rand()%max;
numb3=rand()%max;
}while((numb1-numb2/numb3)<0||numb3==0);
result=numb1-numb2/numb3;
fprintf(fp,"题目%d:%d-%d/%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d-%d/%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
default:printf("ERROR\n");
}
break;
case 3 :
switch(op2){
case 1 : //op1为乘法,op2为加法的情况
result=numb1*numb2+numb3;
fprintf(fp,"题目%d:%d*%d+%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d*%d+%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 2 : //op1为乘法,op2为减法的情况
do{
numb1=rand()%max;
numb2=rand()%max;
numb3=rand()%max;
}while((numb1*numb2-numb3)<0);
result=numb1*numb2-numb3;
fprintf(fp,"题目%d:%d*%d-%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d*%d-%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 3 : //op1为乘法,op2为乘法的情况
result=numb1*numb2*numb3;
fprintf(fp,"题目%d:%d*%d*%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d*%d*%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 4 : //op1为乘法,op2为除法的情况
do{
numb3=rand()%max;
}while(numb3==0);
temp1=numb1*numb2;
temp=gcd(temp1,numb3);
fprintf(fp,"题目%d:%d*%d/%d=%d/%d\n",i,numb1,numb2,numb3,temp1/temp,numb3/temp);
fclose(fp);
fprintf(fb,"题目%d:%d*%d/%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
default:printf("ERROR\n");
}
break;
case 4 :
switch(op2){
case 1 : //op1为除法,op2为加法的情况
do{
numb2=rand()%max;
}while(numb2==0);
temp=gcd(numb1,numb2);
fprintf(fp,"题目%d:%d/%d+%d=%d'%d/%d\n",i,numb1,numb2,numb3,numb3,numb1/temp,numb2/temp);
fclose(fp);
fprintf(fb,"题目%d:%d/%d+%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 2 : //op1为除法,op2为减法的情况
do{
numb3=rand()%max;
}while( (numb1/numb2-numb3)<0||numb2==0);
result=numb1/numb2-numb3;
fprintf(fp,"题目%d:%d/%d-%d=%d\n",i,numb1,numb2,numb3,result);
fclose(fp);
fprintf(fb,"题目%d:%d/%d-%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 3 : //op1为除法,op2为乘法的情况
do{
numb2=rand()%max;
}while(numb2==0);
temp1=numb1*numb3;
temp=gcd(temp1,numb2);
result=numb1/numb2*numb3;
fprintf(fp,"题目%d:%d/%d*%d=%d/%d\n",i,numb1,numb2,numb3,temp1/temp,numb2/temp);
fclose(fp);
fprintf(fb,"题目%d:%d/%d*%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
case 4 : //op1为除法,op2为除法的情况
do{
numb2=rand()%max;
numb3=rand()%max;
}while(numb3==0||numb2==0);
result=numb1/numb2/numb3;
temp1=numb2*numb3;
temp=gcd(temp1,numb1);
fprintf(fp,"题目%d:%d/%d/%d=%d/%d\n",i,numb1,numb2,numb3,numb1/temp,temp1/temp);
fclose(fp);
fprintf(fb,"题目%d:%d/%d/%d%=\n",i,numb1,numb2,numb3);
fclose(fb);
break;
default:printf("ERROR\n");
}
break;
default:printf("ERROR\n");
}
return 0;
}
知识兔主函数通过获取输入的题目数量和随机生成值的最大数,并将数值传到相对应用到的函数:
int main()
{
int subnumber,max;
int opnum;
int operationone(int numb1,int numb2,int max,int i); //函数的声明
int operationtwo(int numb1,int numb2,int numb3,int max,int i);
FILE *fp;
fp=fopen("Exercises.txt","w");
fp=fopen("Answers.txt","w"); //建立文件
fclose(fp);
srand((unsigned)time(0)); //为保证每次运行程序的时候生成的题目都不一样
printf("************随机生成四则运算题目************\n");
printf("请输入题目数量:\n");
scanf("%d",&subnumber);
printf("请输入生成的随机数范围大小:\n");
scanf("%d",&max);
for(i=1;i<=subnumber;i++) //for循环生成题目
{
opnum=rand()%2+1;
switch(opnum)
{
case 1 : //当随机数是生成1个运算符时
numb1=rand()%max;
numb2=rand()%max;
operationone(numb1,numb2,max,i); //执行函数的同时得同时执行把表达式输出到txt文件中
break;
case 2 : //当随机数是生成2个运算符时
numb1=rand()%max;
numb2=rand()%max;
numb3=rand()%max;
operationtwo(numb1,numb2,numb3,max,i);
break;
default:printf("ERROR\n");
}
}
return 0;
}
知识兔六.测试运行
主界面:
生成的Answers.txt文件:
生成的Exercices.txt文件:
生成一万道题目:
七.项目总结
这一次的结对编程让我们懂得了结对编程的意义所在,也更好地感受到编程的乐趣,,通过两个人的分工合作体会到软件工程确实不简单,虽然是两个人而已,但我们感觉到团队配合是多么重要,这次的作业中我们也有很多地方要求没实现,真分数的地方我们只实现了一到两个运算符的输出,当然三个运算符的实现我们是有思路的,我们在网上有对应查到用栈实现,但因为数据结构学得不好,不太会运用,这也坚定我们得学好相关知识的决心,总得来说,虽然这次作业完全度不是那么完美,但我们还是从中学到了不少东西,也期待下一次的团队作业能从中学到更多东西。