加减法的生成
软件工程开课两周了,实质上的作业就是一个,写代码随机生成供小学生使用的算术式。第一感觉,没啥感觉。。以为软件工程又是可以混的一门课。。但是,当我阅读了《软件工程——构建之法》之后,顿时对其改观,这是一本难得的能让我看下去的教科书,而且他讲述的内容也令我感到很熟悉。还记得当初学院里有个让我感到很自豪的项目叫“让优秀的学生更优秀”,很幸运的是,我被划到了张老师门下,张老师与我见面后扯了一大堆,具体的已经淡忘,但他着重提到的一个职业——架构师一直印在我的心上,读了《构建之法》我发现里面讲的就是成为一个架构师的秘籍,遂我就像一个得到了绝世武功秘籍的修士对其进行精读并实践,高兴的像个猴子。
就拿这个随机加减法的生成为例,版本1.0:
我以为,这是个很简单的小程序,于是,一个不太常见的srand函数和几个if结束了这个不成熟的版本,代码如下:
void main() { int a,b,c,p,i; srand(time(0)); printf("题目如下:\n"); for(i=0;i<20;i++) { a=rand()%101; b=rand()%101; p=rand()%2; if(p==1) printf("%d+%d=\n",a,b); if(p==0) { if(a<b) { c=a; a=b; b=c; } printf("%d-%d=\n",a,b); } } }
每次码完代码,诸如怎么把这个代码写得更加高大上之类的想法总会涌上心头,但是通常会因为各种因素而难以实现(主要是懒),这次很幸运的是老师又对这个代码进行了要求添加,支持多项式,支持括号,支持balabala总之是一大堆要求,于是,别懒了,继续写,1.1版本诞生。这个版本我添加了乘除法功能、数字大小上限功能,另外也对乘除法的输出进行了优化,具体就是把C语言里的乘除号* /改成了人类日常熟知的乘除号× ÷(虽然没有任何卵用,但这也是对用户体验的一种提升啊!!!)。下面贴上代码:
#include <stdio.h> #include<stdlib.h> #include<time.h> #include<math.h> int multiplication(long num) //有乘除法 { int a,b,c,p,i; int x = num+1; a=rand()%x; b=rand()%x; p=rand()%4; if(p==0) { if(a<b) { c=a; a=b; b=c; } printf(" %d-%d=\n",a,b); } if(p==1) printf(" %d+%d=\n",a,b); if(p==2) printf(" %d×%d=\n",a,b); if(p==3) printf(" %d÷%d=\n",a,b); } void no_multiplication(long num) //无乘除法 { int a,b,c,p,i; int x = num+1; a=rand()%x; b=rand()%x; p=rand()%2; if(p==1) printf(" %d+%d=\n",a,b); if(p==0) { if(a<b) { c=a; a=b; b=c; } printf(" %d-%d=\n",a,b); } } int main() { int i; //计数器 long num; //数据范围极限 char IsMul[5]; srand(time(0)); printf("请输入算数题目范围(即所允许的最大值)\n"); scanf("%ld",&num); printf("请输入是否加入乘除法,‘yes’ OR ‘no’\n"); scanf("%s",IsMul); printf("***********************题目为:***********************\n"); if(strcmp(IsMul,"yes")==0) { for(i=0;i<20;i++) multiplication(num); } else { for(i=0;i<20;i++) no_multiplication(num); } return 0; }
很明显,代码多了好多,不过我想再加个生成多项式的功能,反观以上两次代码,明显并不能实现这个需求,于是,代码推翻重写,版本1.2上线。更新内容:多项式生成,式子的生成不再像以前那样用if else配合固定形式输出,而是把数与运算符分开,一切都随机生成,代码如下:
#include <stdio.h> #include <stdlib.h> #include "time.h" #include "math.h" #include "string.h" long num_limit; //数据极限 int bol_Mul; //是否有乘除法的判断 /* 函数声明 */ void Muliplication_Judge(); //是否有乘除法并生成相应符号 void Formula_Create(); //多项式的生成 int main() { int i; char IsMul[5]; srand(time(0)); printf("请输入算数题目范围(即所允许的最大值)\n"); scanf("%ld",&num_limit); printf("请输入是否加入乘除法,‘yes’ OR ‘no’\n"); scanf("%s",IsMul); if(strcmp(IsMul,"yes")==0) bol_Mul = 1; else bol_Mul = 0; printf("***********************题目为:***********************\n"); for(i = 0;i<30;i++) Formula_Create(); return 0; } void Muliplication_Judge() { int p; char symbol[5]; if(bol_Mul == 1) { p = rand()%4; switch(p) { case 0:strcpy(symbol,"+");break; case 1:strcpy(symbol,"-");break; case 2:strcpy(symbol,"×");break; case 3:strcpy(symbol,"÷");break; } } else { p = rand()%2; switch(p) { case 0:strcpy(symbol,"+");break; case 1:strcpy(symbol,"-");break; } } printf("%s",symbol); } void Formula_Create() { int i; int p=1; int a; while(p<2){ p = rand()%3; } printf(" "); for (i=0;i<p-1;i++) { a= rand()%num_limit; printf("%d",a); Muliplication_Judge(); } a = rand()%num_limit; printf("%d",a); printf("=\n"); }
1.2之后,我要加入的功能是随机嵌套括号,这个功能不再是前面那样的体力活了,所以我还没实现。。。暂时有个设想还没来得及做完,就是改变1.2版本中数字与运算符完全分开的做法,再增加一个可以生成随机二项式的函数,这样就能对其进行括号嵌套。期待我的1.3版本。。。。
下面说说最近的一些感受。
写好一个项目对底层架构的要求很高,就像建座大厦,地基不稳,大厦必不稳固。回想1.1版本和1.2版本的推翻重写,如果事先对整个工程进行预估,估计重写量会少很多,《构建之法》中提到一个方法——把函数单调化,就是一个函数只实现一个功能,我认为对这种情况很适用。
另外,最近群里助教们发了不少优秀同学blog的链接,我看了不少,第一感觉心里是崩溃的,一直没想到民间有那么多高手,自己以前着实是坐井观天了,结合自身我总结了一句话:“成才路上,不仅要学习技能,更要学习如何展示你的技能”。举个例子,Ray同学的那个app看得我很蛋疼。。。。就是几个按钮,几个跳转,做过Android的不傻都会做,但是我没做,他做了,这就是一种优秀。
最近要做的事情实在太多(前几天闲得蛋疼疯狂接比赛),于是得了选择恐惧症,竟不知道具体该做什么,浑浑噩噩了两天,还因为耳机听太多大脑疲劳。。反而看《构建之法》的时候让我感到了久违的轻松,这就是一本故事会。。事情越多越能锻炼人,这并不能难倒我,Fighting!!!
最后说句牢骚话,cnblogs不能加#笑哭了#表情真是蛋疼。。。