随笔三
合作者
031602148 朱文婧 http://www.cnblogs.com/z031602148/)
031602539 翟丹丹 http://www.cnblogs.com/breakbreak/)
)
设计思路
- 首先,我们讨论后决定利用C语言,不会高端操作,设计程序略微繁琐。
- 编写时决定用多个函数实现,一个主函数交代大概,剩余的分函数具体实现。
- 详细说思路,前面是简单的介绍大致思路,很详细的总函数,还加了个flag,end,判定程序结束,然后是分函数,第一个,没有括号的走起,中间排除了非负整数,然后是打个基础,加减乘除每个都讲一遍,接着走,一个括号的计算,括号在前,中,后各来一遍,看懂一个就行,其他两个照搬,嘻嘻,然后是一个括号里有三个数字的,前中后各来一遍,然后结束,最后那段输出时是总结的一次性输出,大致可以分成四个工作点,主函数,真分数的计算部分,无括号计算,有括号计算,难度依次递加,我包的后两个。
- 大略说思路,也就是在主函数里利用一个随机数,通过switch结构来调用已经编写好的输出固定题型的函数,从而做到题型随机。
分函数就是抓住了一个括号这个点,这个括号在前,在中,在后,还有这个括号里有两个数字和三个数字时的计算。 - 先介绍下字符的意思。
language:用于进行语言切换,其值通过用户输入来决定,1为中文,0为英文。
rig:取right前三个字母,用于统计正确题数;
wro:取wrong前三个字母,用于统计错误题数;
flag:用来控制所出题目的难度。初始时赋值为0,若得到的随机式子的结果为负或真分数函数外得到的随机式子结果不为整数,则不输出该式子且将flag赋值为1,在主函数的循环结构里若flag为1,则不对循环变量i做变动,否则i自增1,代表输出了一道题目。循环的最后会将flag重新赋值为0,为下一次的判断做准备。
test0:用于检测除数是否为0。初值为0,若出现除数为0的情况,则赋值为1,和flag的使用类似,因为是后来添加的,所以没有将这二者合并。
end:用来判断程序是否应该停止。初值设为0。分函数里,把接受答案的变量input的初值设为一个负数,若输入的内容为字符,则input的值不做改变,之后对input的值进行判断,若为负数,则说明用户输入的为字符(输出题目的答案不为负),end值变为1,主函数里对end的值进行判断,若end为1,停止循环,输出结果。
temp:设为float型,用来储存随机出的题目的结果。
test:int型,在计算出temp的值之后会有一条“test=temp”的语句对test的赋值,之后则对test和temp的值是否相等进行判断,若不等,则说明正确答案不为整数,将其放弃不予输出,反之则输出。 - 讨论时已经考虑了非负整数这种情况,降低了难度,后来决定再加一个最大公约数和最小公倍数的计算进行约分,例如4/8直接化成1/2.计算真分数的加减时要做到分母相同,于是写了一个求最小公倍数的函数来实现这一步骤,进而将分子分母扩大相同被倍数进行加减计算。乘除法的计算只要将分子分母按规则相乘即可。
没有括号这部分代码
//输出含0个括号的式子的函数
void zero()
{
srand((unsigned int)time(NULL)); //设置随机数种子
int input=-8,sign[4],i,test;
float temp[5],arr[5];
char sig[4];
for(i=1;i<=4;i++)
{
arr[i]=rand()%10+0;
}
temp[1]=arr[1];
sig[0]='*';
temp[0]=1;
for(i=1;i<=3;i++)
{
sign[i]=rand()%4+1;
if(sign[i]==1)
{
sig[i]='+';
temp[i+1]=temp[i]+arr[i+1];
}
if(sign[i]==2)
{
sig[i]='-';
temp[i+1]=temp[i]-arr[i+1];
}
if(sign[i]==3)
{
sig[i]='*';
if(sig[i-1]=='-')
temp[i+1]=temp[i-1]-arr[i]*arr[i+1];
else if(sig[i-1]=='+')
temp[i+1]=temp[i-1]+arr[i]*arr[i+1];
else
temp[i+1]=temp[i]*arr[i+1];
}
if(sign[i]==4)
{
if(arr[i+1]==0)
{
test0=1;
break;
}
sig[i]='/';
if(sig[i-1]=='-')
temp[i+1]=temp[i-1]-arr[i]/arr[i+1];
else if(sig[i-1]=='+')
temp[i+1]=temp[i-1]+arr[i]/arr[i+1];
else
temp[i+1]=temp[i]/arr[i+1];
}
有一个括号代码
//输出含有一个括号的式子的函数
void kuohao()
{
srand((unsigned int)time(NULL));//设置当前时间为种子
void kuohao1(float big,float arr[5],char sig[4]);
void kuohao2(float big,float arr[5],char sig[4]);
void kuohao3(float big,float arr[5],char sig[4]);
void kuohao4(float arr[5],char sig[4]);
void kuohao5(float arr[5],char sig[4]); //函数声明部分
int i,choose,symbol;
float big,arr[5];
char sig[4];
for(i=1;i<=4;i++)
{
arr[i]=rand()%10+0;
}
arr[2]=rand()%10+1; //避免下一步的除数中出现0
symbol=rand()%4+1;
switch(symbol)
{
case 1:sig[1]='+';big=arr[1]+arr[2];break;
case 2:sig[1]='-';big=arr[1]-arr[2];break;
case 3:sig[1]='*';big=arr[1]*arr[2];break;
case 4:sig[1]='/';big=arr[1]/arr[2];break;
}
choose=rand()%5+1;
switch(choose)
{
case 1:kuohao1(big,arr,sig);break;
case 2:kuohao2(big,arr,sig);break;
case 3:kuohao3(big,arr,sig);break;
case 4:kuohao4(arr,sig);break;
case 5:kuohao5(arr,sig);break;
}
}
这个地方我们有两个疑惑点,一个是考虑0时的除法,写了这一步,arr[2]=rand()%10+1; //避免下一步的除数中出现0。
一个是考虑1加2乘3乘4这种情况,在没有括号里算不出来,放在了有一个括号里。
编码规范#
1.变量与函数的命名要有理有据,尽量做到见名知意,少使用a,b,c之类的作为变量名,以免造成混乱;
2.注意代码的排版,尽量做到层次分明,内容直观,整体美观,比如循环和条件结构处大括号的使用,按层次缩进之类的;
3.勤加注释,特别是在关键的地方。其中,对于某一函数主要功能的解释应单独占一行,标注在函数的开头,便于与普通注释区分;
结果测试#
用中英文各试了下。
提交日志#
两位同学的分工和协作证据截图#
抱歉这个地方出现了bug,我做的是没有括号和一个括号的部分,队友做的是主函数和真分数还有一些补充的零碎部分,在上传完成体时出现了一些conflicts,在contributors上并没有出现这段代码,一开始进行得都很顺利,但是在我们准备提交最终结果的时候,就出了问题,至今还是不知道怎么解决,可能是操作的问题,或者是最后改动太大?
合作过程#
- 开始,一拍即合,选择C语言。
- 然后开始思索思路,感觉挺合拍的,交流无障碍,互相所说的彼此都能理解,理解错误的也能及时指出,然后决定了一个大致编码过程,主函数加分函数,四个点,分工明确。
- 我们的分工就是她负责主函数,剩下的分函数我们各拿一部分,各自写好代码,然后再精修一下,最后拼在一起。
- 在第一次完成后,着重强调了是0到10的四则运算,在除法里加了个排除0的计算,这点一开始就都想到了,在精简过程中考虑到约分化简这个点,找到一些bug,例如在无括号里不能实现的移到有一个括号的就能实现了,修改了下基础程序,最后出来的就是现在比较完整的程序了。
本来是两个人都在git上提交代码的,但是结果只显示了一个人提交了代码,原因为何还在探索中,以后会补上的。
合作体会#
- 因为是第一次合作,也是第一次完成这么大的工作量,程序就比较繁琐,考虑的也很仔细,互相合作肯定比单打独斗高效率,但彼此的空闲时间也会有出入,在另一个人忙时剩余的会默默完成,这点我很感谢队友对我的体谅。
- 俗话说,三个臭皮匠敌一个诸葛亮,众人拾柴火焰高,两个人的智慧一定比一个人苦思冥想来的精致,在合作中会时不时令我出现茅塞顿开的感觉。
- 因为是合作,工作量一下子减少好多,队友是一个细心的人,很多我没有考虑到的地方她都能够指出来,给了我很多指点,合作时也争取把矛盾降到了最低点,包容理解彼此,期待下次合作。在此@朱文婧,撒花感谢。
最后里面还是有一个不足,这也是我们努力之后还是没有完成的,深表遗憾,会继续加油的!