题目要求
本次作业要求两个人合作完成,驾驶员和导航员角色自定,鼓励大家在工作期间角色随时互换,这里会布置两个题目,请各组成员根据自己的爱好任选一题。
- 题目如下: 我们在刚开始上课的时候介绍过一个小学四则运算自动生成程序的例子,请实现它,要求:
- 能够自动生成四则运算练习题
- 可以定制题目数量
- 用户可以选择运算符
- 用户设置最大数(如十以内、百以内等)
- 用户选择是否有括号、是否有小数
- 用户选择输出方式(如输出到文件、打印机等)
- 最好能提供图形用户界面(根据自己能力选做,以完成上述功能为主)
角色定位
- 本人主要担任驾驶员,能够完成全部代码工作,程序基本实现全部要求功能,并将代码上传至coding.net或者GitHub代码托管系统中,并对领航员在此次编程任务中起到的作用做出客观评价。
问题分析
- 四则混合运算的主要问题是随机数的生成和运算符的组合。就随机数而言,在一定范围内可生成整数和小数。就运算符而言,带括号的运算优先级最高。其次是乘除和加减。所以算法问题主要集中在以下几点。 (1)随机数的生成(整数或小数)。 (2)是否有括号。 (3)需要输出哪种运算类型。 (4)输出形式。(直接输出或外部输出)。
算法思路及程序代码
- 首先是主函数部分,用来提供用户选择需求和输出结果。
int main(){ f1 = fopen("result.txt", "w"); printf("请选择数值范围:"); scanf("%d", &m); printf("请选择是否有小数,0为没有,1为有:"); scanf("%d", &xs); printf("请输入算式数量:"); scanf("%d", &sl); printf("请输入是否有括号,0为没有,1为有:"); scanf("%d", &kh); if (kh == 0) { printf("请选择算式类型,0为+,1为-,2为*,3为/,4为随机:"); scanf("%d", &zl); printf("请选择输出形式。0为输出到文件,1为直接输出"); scanf("%d",&gs); nkh(); } else { printf("请选择输出形式。0为输出到文件,1为直接输出"); scanf("%d", &gs); ykh(); } return 0;}
效果图如下:
随机数的产生。
1 整数随机数。
a = rand() % (m)+1; b = rand() % (m)+1; c = rand() % (m)+1; d = rand() % (m)+1;
2 小数随机数。
a = rand() % (m * 10) / 10.0 + 1; b = rand() % (m * 10) / 10.0 + 1; c = rand() % (m * 10) / 10.0 + 1; d = rand() % (m * 10) / 10.0 + 1;
两个调用函数部分。
1 无括号函数。
此函数又可以分为两部分,整数运算和小数运算,具体代码如下。void nkh()//无括号{ double a, b,c,d, t = 0; a = rand() % (m)+1; b = rand() % (m)+1; if (xs==0)//用户不需要小数时调用 { while (sl)//生成的个数控制 { a = rand() % (m)+1; b = rand() % (m)+1; c = rand() % (m)+1; d = rand() % (m)+1; if (zl == 4)//用于实现随机生成四种算式 { t = 1; zl = rand() % 4;//zl将在0123中随机取值 } switch (zl)//通过zl的值输出不同的算式 { case 0://输出加法 { if (gs == 1) { printf("%.0lf+%.0lf+%.0lf+%.0lf\n", a, b,c,d); break; } else { fprintf(f1, "%.0lf+%.0lf+%.0lf+%.0lf\n", a, b,c,d); break; } } case 1://输出减法 { if (a > b) { if (gs == 1) { printf("%.0lf-%.0lf\n", a, b); break; } else { fprintf(f1,"%.0lf-%.0lf\n", a, b); break; } } else { if (gs == 1) { printf("%.0lf-%.0lf\n", b, a); break; } else { fprintf(f1, "%.0lf-%.0lf\n", b, a); break; } } } case 2:if (gs == 1) { printf("%.0lf*%.0lf*%.0lf*%.0lf\n", a, b,c,d); break; }//输出乘法 else{ fprintf(f1,"%.0lf*%.0lf*%.0lf*%.0lf\n", a, b,c,d); break; } case 3:if (gs == 1) { printf("%.0lf/%.0lf\n", a, b); break; }//输出除法 else{ fprintf(f1,"%.0lf/%.0lf\n", a, b); break; } } if (t == 1) { zl = 4; } sl--; } } else//用户需要小数时调用,功能与上面基本相同 { while (sl) { a = rand() % (m * 10) / 10.00 + 1; b = rand() % (m * 10) / 10.00 + 1; c = rand() % (m * 10) / 10.00 + 1; d = rand() % (m * 10) / 10.00 + 1; if (zl == 4) { t = 1; zl = rand() % 4; } switch (zl) { case 0:if (gs == 1) { printf("%.2lf+%.2lf+%.2lf+%.2lf\n", a, b,c,d); break; } else{ fprintf(f1,"%.2lf+%.2lf+%.2lf+%.2lf\n", a, b,c,d); break; } case 1: { if (a > b) { if (gs == 1) { printf("%.2lf-%.2lf\n", a, b); break; } else{ fprintf(f1,"%.2lf-%.2lf\n", a, b); break; } } else { if (gs == 1) { printf("%.2lf-%.2lf\n", b, a); break; } else { fprintf(f1, "%.2lf-%.2lf\n", b, a); break; } } } case 2:if (gs == 1) { printf("%.2lf*%.2lf*%.2lf*%.2lf\n", a, b,c,d); break; } else{ fprintf(f1,"%.2lf*%.2lf*%.2lf*%.2lf\n", a, b,c,d); break; } case 3:if (gs == 1) { printf("%.2lf/%.2lf\n", a, b); break; } else{ fprintf(f1,"%.2lf/%.2lf\n", a, b); break; } } if (t == 1) { zl = 4; } sl--; } } return;}
- 输出效果图如下: (1)直接输出: (2)文件输出: 2 有括号函数,与上述思路基本相同,添加了括号运算。
void ykh()//有括号的多元式{ double a, b, c, d; int tt; if (xs == 0)//没有小数时调用 { while (sl) { a = rand() % (m)+1; b = rand() % (m)+1; c = rand() % (m)+1; d = rand() % (m)+1; tt = rand() % 8;//用于随机生成预设的8种算式格式 switch (tt) { case 0:if (gs == 1) { printf("(%.0lf+%.0lf)*%.0lf/%.0lf\n", a, b, c, d); break; } else{ fprintf(f1,"(%.0lf+%.0lf)*%.0lf/%.0lf\n", a, b, c, d); break; } case 1: { if (a > b) { if (gs == 1) { printf("(%.0lf-%.0lf)*%.0lf/%.0lf\n", a, b, c, d); break; } else{ fprintf(f1,"(%.0lf-%.0lf)*%.0lf/%.0lf\n", a, b, c, d); break; } } else { if (gs == 1) { printf("(%.0lf-%.0lf)*%.0lf/%.0lf\n", b, a, c, d); break; } else { fprintf(f1,"(%.0lf-%.0lf)*%.0lf/%.0lf\n", b, a, c, d); break; } } } case 2:if (gs == 1) { printf("%.0lf*(%.0lf+%.0lf)-%.0lf\n", a, b, c, d); break; } else { fprintf(f1,"%.0lf*(%.0lf+%.0lf)-%.0lf\n", a, b, c, d); break; } case 3:if (gs == 1) { printf("%.0lf/(%.0lf+%.0lf)-%.0lf\n", a, b, c, d); break; } else{ fprintf(f1,"%.0lf/(%.0lf+%.0lf)-%.0lf\n", a, b, c, d); break; } case 4:if (gs == 1) { printf("%.0lf+(%.0lf-%.0lf)*%.0lf\n", a, b, c, d); break; } else{ fprintf(f1,"%.0lf+(%.0lf-%.0lf)*%.0lf\n", a, b, c, d); break; } case 5: { if (a > b) { if (gs == 1) { printf("(%.0lf-%.0lf)*(%.0lf+%.0lf)\n", a, b, c, d); break; } else{ fprintf(f1,"(%.0lf-%.0lf)*(%.0lf+%.0lf)\n", a, b, c, d); break; } } else { if (gs == 1) { printf("(%.0lf-%.0lf)*(%.0lf+%.0lf)\n", b, a, d, c); break; } else { fprintf(f1,"(%.0lf-%.0lf)*(%.0lf+%.0lf)\n", b, a, d, c); break; } } } case 6:if (gs == 1) { printf("(%.0lf+%.0lf)/(%.0lf+%.0lf)\n", a, b, c, d); break; } else { fprintf(f1,"(%.0lf+%.0lf)/(%.0lf+%.0lf)\n", a, b, c, d); break; } case 7: if (gs == 1) { printf("%.0lf-(%.0lf%+%.0lf)/%.0lf\n", a, b, c, d); break; } else { fprintf(f1,"%.0lf-(%.0lf%+%.0lf)/%.0lf\n", a, b, c, d); break; } } sl--; } else//需要小数时调用 { while (sl) { a = rand() % (m * 10) / 10.0 + 1; b = rand() % (m * 10) / 10.0 + 1; c = rand() % (m * 10) / 10.0 + 1; d = rand() % (m * 10) / 10.0 + 1; tt = rand() % 8;//用于随机生成预设的八种表达式 switch (tt) { case 0:if (gs == 1) { printf("(%.2lf+%.2lf)*%.2lf/%.2lf\n", a, b, c, d); break; } else{ fprintf(f1,"(%.2lf+%.2lf)*%.2lf/%.2lf\n", a, b, c, d); break; } case 1: { if (a > b) { if (gs == 1) { printf("(%.2lf-%.2lf)*%.2lf/%.2lf\n", a, b, c, d); break; } else{ fprintf(f1,"(%.2lf-%.2lf)*%.2lf/%.2lf\n", a, b, c, d); break; } } else { if (gs == 1) { printf("(%.2lf-%.2lf)*%.2lf/%.2lf\n", b, a, c, d); break; } else { fprintf(f1,"(%.2lf-%.2lf)*%.2lf/%.2lf\n", b, a, c, d); break; } } } case 2:if (gs == 1) { printf("%.2lf*(%.2lf+%.2lf)-%.2lf\n", a, b, c, d); break; } else { fprintf(f1,"%.2lf*(%.2lf+%.2lf)-%.2lf\n", a, b, c, d); break; } case 3:if (gs == 1) { printf("%.2lf/(%.2lf+%.2lf)-%.2lf\n", a, b, c, d); break; } else{ fprintf(f1,"%.2lf/(%.2lf+%.2lf)-%.2lf\n", a, b, c, d); break; } case 4:if (gs == 1) { printf("%.2lf+(%.2lf-%.2lf)*%.2lf\n", a, b, c, d); break; } else{ fprintf(f1,"%.2lf+(%.2lf-%.2lf)*%.2lf\n", a, b, c, d); break; } case 5: { if (a > b) { if (gs == 1) { printf("(%.2lf-%.2lf)*(%.2lf+%.2lf)\n", a, b, c, d); break; } else{ fprintf(f1,"(%.2lf-%.2lf)*(%.2lf+%.2lf)\n", a, b, c, d); break; } } else { if (gs == 1) { printf("(%.2lf-%.2lf)*(%.2lf+%.2lf)\n", b, a, d, c); break; } else { fprintf(f1,"(%.2lf-%.2lf)*(%.2lf+%.2lf)\n", b, a, d, c); break; } } } case 6:if (gs == 1) { printf("(%.2lf+%.2lf)/(%.2lf+%.2lf)\n", a, b, c, d); break; } else { fprintf(f1,"(%.2lf+%.2lf)/(%.2lf+%.2lf)\n", a, b, c, d); break; } case 7: if (gs == 1) { printf("%.2lf-(%.2lf%+.2lf%)/%.2lf\n", a, b, c, d); break; } else { fprintf(f1,"%.2lf-(%.2lf%+.2lf%)/%.2lf\n", a, b, c, d); break; } } sl--; } } return;}
有括号运算的输出效果图如下所示。
(1)直接输出(整数运算)。 (2)文件输出(小数运算)。- 至此,程序实现了根据用户的需求以不同的形式输出四则运算的试题,问题得以解决。
源代码地址。
总结及评价
- 第2次结对编程相对于第一次难度有所提升,但在两个人得通力合作下还是圆满得完成了此次作业。本次作业让我明白了结对编程任务中驾驶员和领航员的角色定位和功能。作为驾驶员要设计出源代码及对代码功能注释,领航员起到辅助测试和引导的作用。本次结对编程中,领航员袁坤对我的代码设计和功能测试起到了很大的作用,在完成作业的过程中,我们做到了角色互换和及时沟通,中间遇到的问题得到了及时的解决,使我深刻的意识到了结对编程的优点。希望在以后的团队作业中能更好的发挥自己的角色功能,更好的学习借鉴他人的优点。