整体功能简介:题目不重复;可以定制数量;可以自己选择输入范围;可以选择是否添加乘除法;选择除法结果是以商加余数形式表示还是小数方式表示;支持分数计算;可以判断正误,如果错误能给出正确答案。
不足之处:题目不重复的前提是数值范围比较大而且数量相对少,相反的情况就可能出现重复了;乘法结果数值偏大,除法基本没有整除的情况(不太符合小学除法的命题规则);分数不区分真假分数,当选择添加分数的时候只有分数算法,而且会出现负值(也不符合小学生出题要求);最致命的是只能给出两元运算。先大致编出来,后期进行优化。
我的基础十分薄弱,只能用C语言编写简单的程序,虽然这个小程序不难,但是我却写了三个晚上,加起来有十多个小时吧,而且还有这么多缺陷,不过还好我大致编出来了。我先把编写过程中遇到的问题总结一下,再附上源代码。
我判断随机符号是先生成随机数再根据随机数取余来添加随机符号的,一开始数值范围为正,后来添加负数的时候总是出错,单步调试之后才知道我的判断语句里面只有0,1,2,3。根本没负数嘛。我把随机数取绝对值然后再取余就行了。
在写除法的结果用小数表示的时候定义了两个double类型的变量,输入的时候写的是%f(其实就是这里错了),然后每次判断对错的时候总是错的,即使输入的是对的,一开始以为是浮点数的比较出问题了,认为输入的浮点数小数点后面就只有输入的几位(自己都忍不住笑了),然后抓着这个问题不放了,一番苦战无果后决定又感觉是输入的数出错了(这次感觉对了)。然后又是一番苦战才找到时输入格式写错了,双精度类型的输入格式是“%lf”,我当时看错了改成“%1f”,还是错,还是苦战,最后才发现错在哪。汗!基本功不扎实真坑,太坑了!就这么一点程序整了半天。
1 void DivMod(int a,int b) 2 { 3 int c,d; //存放结果和余数 4 5 printf("%d/%d=",a,b); 6 scanf("%d",&c); //输入结果 7 printf("请输入余数:"); 8 scanf("%d",&d); //输入余数 9 if(c==(a/b)&&d==(a%b)) //判断结果和余数是否相同 10 printf("right!\n"); 11 else 12 printf("error!the right answer is %d %d.\n",(a/b),(a%b)); 13 14 }
涉及分数的加减乘除里面要约分,求最小公倍数,求最大公约数,还好以前写过一个分数算法小程序,贴过来修改一下基本就行了,调试的时候分数减法的参数传递时又出现问题了,不过调试一下也算找到问题了,没有之前那么艰难。
其他的小问题也不少,但是没有完全记下来。程序也比较简单,就不吹嘘功能了。
估计以后的优化会很艰难,直接重写一份也是有可能的。毕竟问题太多了,到处都是不合理的地方。先大致写出来给自己点信心(这小程序我也会写的嘛),然后优化好以后和这个对比一下(自嘲当初的根本不能看嘛),让程序的不断优化见证自己的进步。
下面附上源代码:
1 // 加减习题.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include<stdio.h> 6 #include<stdlib.h> 7 #include<time.h> 8 #include<math.h> 9 10 void DivMod(int,int); //除法结果选择有余数时子函数 11 void DivDec(int,int); //除法结果选择小数时子函数 12 int gys(int,int); //求最大公约数函数 13 int gbs(int,int); //求最小公倍数函数 14 void yuefen(int,int,int,int); //定义约分以及判断正误函数 15 void FraAri(char,int,int); //分数运算 16 17 //生成一个小于x的随机数。rand()函数生成一个无符号型的随机数,然后模x,即结果为0到x内的一个随机数 ,然后将这个值赋给random(x) 18 //#define random(x) (rand()%(x)) 19 20 21 int main(int argc, char *argv[]) 22 { 23 int i; //循环变量 24 int temp; //临时变量 25 int number; //题目数量 26 int a,b,c,d; //a,b用来存储随机数,c存储运算结果,d存储输入的数值 27 int m,n; //m,n确定数值范围 28 int temp0,temp1,temp2=2,temp3,temp4; //选择是否加入乘除法,是否有余数以及其他选择变量 29 30 31 char op[4]={‘+‘,‘-‘,‘*‘,‘/‘}; 32 33 srand((unsigned int)time(NULL)); //利用系统时间来改变系统的种子值,即srand(time(NULL)) 34 35 printf("题目数量:\n"); 36 scanf("%d",&number); //输入题目数量 37 38 printf("输入数值范围(整数):\n"); 39 scanf("%d%d",&m,&n); //输入数值范围 40 41 printf("是否添加乘除法,否输入0,是输入1:\n"); 42 scanf("%d",&temp0); //选择是否有乘除法 43 44 if(temp0==1) //选择除法结果方式 45 { 46 temp2=4; 47 printf("除法结果取整输入0,取余数输入1,取小数(两位)输入2:\n"); 48 scanf("%d",&temp4); 49 } 50 51 printf("是否添加分数算法,否输入0,是输入1:\n"); 52 scanf("%d",&temp3); 53 54 55 56 for(i=0;i<number;i++) 57 { 58 a=rand()%(n-m)+m; 59 b=rand()%(n-m)+m; //a,b产生随机数 60 temp1=abs(a)%temp2; //使用取绝对值函数abs,保证被除数为正,便于case语句执行 61 switch(temp1) 62 { 63 case 0: //加法 64 if(temp3==1) //加法分数 65 { 66 FraAri(‘+‘,m,n); 67 continue; 68 } 69 c=a+b; 70 break; 71 case 1: //减法 72 if(temp3==1) //减法分数 73 { 74 FraAri(‘-‘,m,n); 75 continue; 76 } 77 if(a<b) //保证大数减小数 78 { 79 temp=a; 80 a=b; 81 b=temp; 82 } 83 c=a-b; 84 break; 85 case 2: //乘法 86 if(temp3==1) //乘法分数 87 { 88 FraAri(‘*‘,m,n); 89 continue; 90 } 91 c=a*b; 92 break; 93 case 3: //除法 94 if(temp3==1) //除法分数 95 { 96 FraAri(‘/‘,m,n); 97 continue; 98 } 99 if(b==0) 100 { 101 b=1; //如果除数为零直接赋值1 102 } 103 if(temp4==1) //除法结果形式为商和余数 104 { 105 DivMod(a,b); 106 continue; 107 } 108 else if(temp4==2) //除法结果小数形式 109 { 110 DivDec(a,b); 111 continue; 112 } 113 else //除法结果取整 114 { 115 c=a/b; 116 } 117 break; 118 } 119 if(b<0) //判断是否加括号,负数 120 { 121 printf("%d%c(%d)=",a,op[temp1],b); 122 } 123 else 124 { 125 printf("%d%c%d=",a,op[temp1],b); 126 } 127 128 scanf("%d",&d); //输入结果 129 if(c==d) //判断对错 130 printf("right!\n"); 131 else 132 printf("error!the right answer is %d.\n",c); 133 } 134 135 printf("\n"); 136 137 return 0; 138 } 139 140 void DivMod(int a,int b) 141 { 142 int c,d; //存放结果和余数 143 144 printf("%d/%d=",a,b); 145 scanf("%d",&c); //输入结果 146 printf("请输入余数:"); 147 scanf("%d",&d); //输入余数 148 if(c==(a/b)&&d==(a%b)) //判断结果和余数是否相同 149 printf("right!\n"); 150 else 151 printf("error!the right answer is %d %d.\n",(a/b),(a%b)); 152 153 } 154 155 void DivDec(int a,int b) 156 { 157 double c,d; //存放输入结果和运算结果 158 // int temp; //临时变量 159 printf("%d/%d=",a,b); 160 scanf("%lf",&c); //结果输入 161 d=(float)a/b; 162 d*=100; //四舍五入取小数余数 163 d+=0.5; 164 d=floor(d); //利用floor()函数得到最接近d数,但不大于d的整数(完成四舍五入) 165 d/=100; 166 // temp=(int)d; 167 if((d-c)==0) 168 printf("right!\n"); 169 else 170 // printf("%f \n",c); 171 printf("error!the right answer is %f.\n",d); 172 } 173 174 int gys(int a,int b) //求最大公约数函数 175 { 176 return b?gys(b,a%b):a; //递归调用gys,利用条件语句返回最大公约数 177 } 178 179 int gbs(int a,int b) //求最小公倍数函数 180 { 181 return a*b/gys(a,b); 182 } 183 184 void yuefen(int a,int b,int ans1,int ans2) //约分函数 185 { 186 int s=gys(a,b); 187 a/=s; 188 b/=s; 189 if(a==ans1&&b==ans2) 190 printf("right!"); 191 else if(b<0) 192 printf("error!the result is %d/(%d)\n",a,b); 193 else 194 printf("error!the result is %d/%d\n",a,b); 195 } 196 197 void FraAri(char op,int m,int n) 198 { 199 int a,b,c,d; //分数加数和被加数的两个分子分母 200 int x,y; //加减法运算时的临时变量 201 int ans1,ans2; //存放输入的分子分母 202 a=rand()%(n-m)+m; 203 b=rand()%(n-m)+m; 204 c=rand()%(n-m)+m; 205 d=rand()%(n-m)+m; //a,b,c,d产生随机数 206 207 printf("(%d/%d)%c(%d/%d)=",a,b,op,c,d); 208 scanf("%d%d",&ans1,&ans2); 209 210 switch(op) //根据输入的符号选择不同函数的调用 211 { 212 case ‘+‘: //调用分数加法函数 213 x=gbs(b,d); 214 y=x/b*a+x/d*c; 215 yuefen(y,x,ans1,ans2); 216 break; 217 case ‘-‘: //调用分数减法函数 218 x=gbs(b,d); 219 y=x/b*a-x/d*c; 220 yuefen(y,x,ans1,ans2); 221 break; 222 case ‘*‘:yuefen(a*c,b*d,ans1,ans2);break; //调用分数乘法函数 223 case ‘/‘:yuefen(a*d,b*c,ans1,ans2);break; //调用分数除法函数 224 // default:printf("error\n");break; 225 } 226 }
原文:http://www.cnblogs.com/dreamq/p/5273361.html