一.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函数是当运算符为一个时候的情况下,通过随机生成的运算符类型(一到四分别对应加减乘除),然后转入到相对应的情况。
1 int operationone(int numb1,int numb2,int max,int i) //不一定是整型函数 2 { 3 int gcd(int numb1,int numb2); 4 int temp;//中间值 5 int result; 6 op1=rand()%4+1; //op1的生成值为1到4,分别对应加法,减法,乘法,除法 7 fb=fopen("Exercises.txt","a"); 8 fp=fopen("Answers.txt","a");//打开文件 9 switch(op1){ 10 case 1: //op1为1的时候,执行加法操作 11 result=numb1+numb2; 12 fprintf(fp,"题目%d:%d+%d=%d\n",i,numb1,numb2,result); //写入文件 13 fclose(fp); //关闭文件 14 fprintf(fb,"题目%d:%d+%d=\n",i,numb1,numb2); 15 fclose(fb); 16 break; 17 case 2 : //op1为2的时候,执行减法操作; 18 if(numb1//为保证结果不为零,当出现生成的被减数比减数小,进行两者值的交换 19 { 20 temp=numb1; 21 numb2=numb1; 22 numb1=temp; 23 } 24 result=numb1-numb2; 25 fprintf(fp,"题目%d:%d-%d = %d\n",i,numb1,numb2,result); 26 fclose(fp); 27 fprintf(fb,"题目%d:%d-%d = \n",i,numb1,numb2); 28 fclose(fb); 29 break; 30 case 3 : //op1为3的时候,执行乘法操作; 31 result=numb1*numb2; 32 fprintf(fp,"题目%d:%d*%d = %d\n",i,numb1,numb2,result); 33 fclose(fp); 34 fprintf(fb,"题目%d:%d*%d = \n",i,numb1,numb2); 35 fclose(fb); 36 break; 37 case 4 : //op1为4的时候,执行除法操作; 38 if(numb2==0) 39 numb2=rand()%max+1; 40 temp=gcd(numb1,numb2); 41 fprintf(fp,"题目%d:%d/%d = %d/%d\n",i,numb1,numb2,numb1/temp,numb2/temp); 42 fclose(fp); 43 fprintf(fb,"题目%d:%d/%d = \n",i,numb1,numb2); 44 fclose(fb); 45 break; 46 default:printf("ERROR\n"); 47 } 48 return 0; 49 }
gcd辗转相除法
1 int gcd(int numb1,int numb2)//辗转相除法 2 { 3 if(numb2==0) return numb1; 4 return gcd(numb2,numb1%numb2); 5 }
运算符为两个的情况下:
1 int operationtwo(int numb1,int numb2,int numb3,int max) 2 { 3 int gcd(int numb1,int numb2); 4 int result, result1,temp,temp1; 5 op1=rand()%4+1; 6 op2=rand()%4+1; //op1,op2的生成值为1到4,分别对应加法,减法,乘法,除法 7 fp=fopen("Answers.txt","a"); 8 fb=fopen("Exercises.txt","a"); 9 switch(op1){ 10 case 1 : 11 switch(op2){ 12 case 1 : //op1,op2均为加法的情况 13 result1=numb1+numb2; 14 result=result1+numb3; 15 fprintf(fp,"题目%d:%d+%d+%d%=%d\n",i,numb1,numb2,numb3,result); 16 fclose(fp); 17 fprintf(fb,"题目%d:%d+%d+%d%=\n",i,numb1,numb2,numb3); 18 fclose(fb); 19 break; 20 case 2 : //op1为加法,op2为减法的情况 21 result1=numb1+numb2; 22 if(result1<numb3) 23 { 24 temp=numb3; 25 numb3=numb2; 26 numb2=temp; 27 } 28 result=numb1+numb2-numb3; 29 fprintf(fp,"题目%d:%d+%d-%d=%d\n",i,numb1,numb2,numb3,result); 30 fclose(fp); 31 fprintf(fb,"题目%d:%d+%d-%d%=\n",i,numb1,numb2,numb3); 32 fclose(fb); 33 break; 34 case 3 : //op1为加法,op2为乘法的情况 35 result1=numb2*numb3; 36 result=numb1+result1; 37 fprintf(fp,"题目%d:%d+%d*%d=%d\n",i,numb1,numb2,numb3,result); 38 fclose(fp); 39 fprintf(fb,"题目%d:%d+%d*%d%=\n",i,numb1,numb2,numb3); 40 fclose(fb); 41 break; 42 case 4 : //op1为加法,op2为除法的情况 43 if(numb3==0) 44 { 45 numb3=rand()%max+1; 46 } 47 temp=gcd(numb2,numb3); 48 fprintf(fp,"题目%d:%d+%d/%d=%d'%d/%d\n",i,numb1,numb2,numb3,numb1,numb2/temp,numb3/temp); 49 fclose(fp); 50 fprintf(fb,"题目%d:%d+%d/%d%=\n",i,numb1,numb2,numb3); 51 fclose(fb); 52 break; 53 default:printf("ERROR\n"); 54 } 55 break; 56 case 2 : 57 switch(op2){ 58 case 1 : //op1为减法,op2为加法的情况 59 if(numb1//为保证结果不为零,当出现生成的被减数比减数小,进行两者值的交换 60 { 61 temp=numb1; 62 numb2=numb1; 63 numb1=temp; 64 } 65 result=numb1-numb2+numb3; 66 fprintf(fp,"题目%d:%d-%d+%d=%d\n",i,numb1,numb2,numb3,result); 67 fclose(fp); 68 fprintf(fb,"题目%d:%d-%d+%d%=\n",i,numb1,numb2,numb3); 69 fclose(fb); 70 break; 71 case 2 : //op1为减法,op2为减法的情况 72 do{ 73 numb1=rand()%max; 74 numb2=rand()%max; 75 numb3=rand()%max; 76 }while((numb1-numb2-numb3)<=0); 77 result=numb1-numb2-numb3; 78 fprintf(fp,"题目%d:%d-%d-%d=%d\n",i,numb1,numb2,numb3,result); 79 fclose(fp); 80 fprintf(fb,"题目%d:%d-%d-%d%=\n",i,numb1,numb2,numb3); 81 fclose(fb); 82 break; 83 case 3 : //op1为减法,op2为乘法的情况 84 do{ 85 numb1=rand()%max; 86 numb2=rand()%max; 87 numb3=rand()%max; 88 }while((numb1-numb2*numb3)<0); 89 result=numb1-numb2*numb3; 90 fprintf(fp,"题目%d:%d-%d*%d=%d\n",i,numb1,numb2,numb3,result); 91 fclose(fp); 92 fprintf(fb,"题目%d:%d-%d*%d%=\n",i,numb1,numb2,numb3); 93 fclose(fb); 94 break; 95 case 4 : //op1为减法,op2为除法的情况 96 do{ 97 numb1=rand()%max; 98 numb2=rand()%max; 99 numb3=rand()%max; 100 }while((numb1-numb2/numb3)<0||numb3==0); 101 result=numb1-numb2/numb3; 102 fprintf(fp,"题目%d:%d-%d/%d=%d\n",i,numb1,numb2,numb3,result); 103 fclose(fp); 104 fprintf(fb,"题目%d:%d-%d/%d%=\n",i,numb1,numb2,numb3); 105 fclose(fb); 106 break; 107 default:printf("ERROR\n"); 108 } 109 break; 110 case 3 : 111 switch(op2){ 112 case 1 : //op1为乘法,op2为加法的情况 113 result=numb1*numb2+numb3; 114 fprintf(fp,"题目%d:%d*%d+%d=%d\n",i,numb1,numb2,numb3,result); 115 fclose(fp); 116 fprintf(fb,"题目%d:%d*%d+%d%=\n",i,numb1,numb2,numb3); 117 fclose(fb); 118 break; 119 case 2 : //op1为乘法,op2为减法的情况 120 do{ 121 numb1=rand()%max; 122 numb2=rand()%max; 123 numb3=rand()%max; 124 }while((numb1*numb2-numb3)<0); 125 result=numb1*numb2-numb3; 126 fprintf(fp,"题目%d:%d*%d-%d=%d\n",i,numb1,numb2,numb3,result); 127 fclose(fp); 128 fprintf(fb,"题目%d:%d*%d-%d%=\n",i,numb1,numb2,numb3); 129 fclose(fb); 130 break; 131 case 3 : //op1为乘法,op2为乘法的情况 132 result=numb1*numb2*numb3; 133 fprintf(fp,"题目%d:%d*%d*%d=%d\n",i,numb1,numb2,numb3,result); 134 fclose(fp); 135 fprintf(fb,"题目%d:%d*%d*%d%=\n",i,numb1,numb2,numb3); 136 fclose(fb); 137 break; 138 case 4 : //op1为乘法,op2为除法的情况 139 do{ 140 numb3=rand()%max; 141 }while(numb3==0); 142 temp1=numb1*numb2; 143 temp=gcd(temp1,numb3); 144 fprintf(fp,"题目%d:%d*%d/%d=%d/%d\n",i,numb1,numb2,numb3,temp1/temp,numb3/temp); 145 fclose(fp); 146 fprintf(fb,"题目%d:%d*%d/%d%=\n",i,numb1,numb2,numb3); 147 fclose(fb); 148 break; 149 default:printf("ERROR\n"); 150 } 151 break; 152 case 4 : 153 switch(op2){ 154 case 1 : //op1为除法,op2为加法的情况 155 do{ 156 numb2=rand()%max; 157 }while(numb2==0); 158 temp=gcd(numb1,numb2); 159 fprintf(fp,"题目%d:%d/%d+%d=%d'%d/%d\n",i,numb1,numb2,numb3,numb3,numb1/temp,numb2/temp); 160 fclose(fp); 161 fprintf(fb,"题目%d:%d/%d+%d%=\n",i,numb1,numb2,numb3); 162 fclose(fb); 163 break; 164 case 2 : //op1为除法,op2为减法的情况 165 do{ 166 numb3=rand()%max; 167 }while( (numb1/numb2-numb3)<0||numb2==0); 168 result=numb1/numb2-numb3; 169 fprintf(fp,"题目%d:%d/%d-%d=%d\n",i,numb1,numb2,numb3,result); 170 fclose(fp); 171 fprintf(fb,"题目%d:%d/%d-%d%=\n",i,numb1,numb2,numb3); 172 fclose(fb); 173 break; 174 case 3 : //op1为除法,op2为乘法的情况 175 do{ 176 numb2=rand()%max; 177 }while(numb2==0); 178 temp1=numb1*numb3; 179 temp=gcd(temp1,numb2); 180 result=numb1/numb2*numb3; 181 fprintf(fp,"题目%d:%d/%d*%d=%d/%d\n",i,numb1,numb2,numb3,temp1/temp,numb2/temp); 182 fclose(fp); 183 fprintf(fb,"题目%d:%d/%d*%d%=\n",i,numb1,numb2,numb3); 184 fclose(fb); 185 break; 186 case 4 : //op1为除法,op2为除法的情况 187 do{ 188 numb2=rand()%max; 189 numb3=rand()%max; 190 }while(numb3==0||numb2==0); 191 result=numb1/numb2/numb3; 192 temp1=numb2*numb3; 193 temp=gcd(temp1,numb1); 194 fprintf(fp,"题目%d:%d/%d/%d=%d/%d\n",i,numb1,numb2,numb3,numb1/temp,temp1/temp); 195 fclose(fp); 196 fprintf(fb,"题目%d:%d/%d/%d%=\n",i,numb1,numb2,numb3); 197 fclose(fb); 198 break; 199 default:printf("ERROR\n"); 200 } 201 break; 202 default:printf("ERROR\n"); 203 } 204 return 0; 205 }
主函数通过获取输入的题目数量和随机生成值的最大数,并将数值传到相对应用到的函数:
1 int main() 2 { 3 int subnumber,max; 4 int opnum; 5 int operationone(int numb1,int numb2,int max,int i); //函数的声明 6 int operationtwo(int numb1,int numb2,int numb3,int max,int i); 7 FILE *fp; 8 fp=fopen("Exercises.txt","w"); 9 fp=fopen("Answers.txt","w"); //建立文件 10 fclose(fp); 11 srand((unsigned)time(0)); //为保证每次运行程序的时候生成的题目都不一样 12 printf("************随机生成四则运算题目************\n"); 13 printf("请输入题目数量:\n"); 14 scanf("%d",&subnumber); 15 printf("请输入生成的随机数范围大小:\n"); 16 scanf("%d",&max); 17 for(i=1;i<=subnumber;i++) //for循环生成题目 18 { 19 opnum=rand()%2+1; 20 switch(opnum) 21 { 22 case 1 : //当随机数是生成1个运算符时 23 numb1=rand()%max; 24 numb2=rand()%max; 25 operationone(numb1,numb2,max,i); //执行函数的同时得同时执行把表达式输出到txt文件中 26 break; 27 case 2 : //当随机数是生成2个运算符时 28 numb1=rand()%max; 29 numb2=rand()%max; 30 numb3=rand()%max; 31 operationtwo(numb1,numb2,numb3,max,i); 32 break; 33 default:printf("ERROR\n"); 34 } 35 } 36 return 0; 37 }
六.测试运行
主界面:
生成的Answers.txt文件:
生成的Exercices.txt文件:
生成一万道题目:
七.项目总结
这一次的结对编程让我们懂得了结对编程的意义所在,也更好地感受到编程的乐趣,,通过两个人的分工合作体会到软件工程确实不简单,虽然是两个人而已,但我们感觉到团队配合是多么重要,这次的作业中我们也有很多地方要求没实现,真分数的地方我们只实现了一到两个运算符的输出,当然三个运算符的实现我们是有思路的,我们在网上有对应查到用栈实现,但因为数据结构学得不好,不太会运用,这也坚定我们得学好相关知识的决心,总得来说,虽然这次作业完全度不是那么完美,但我们还是从中学到了不少东西,也期待下一次的团队作业能从中学到更多东西。
合作者:余晓东 3117004635
肖烈涛 3117004632