自动生成四则运算题目
主要功能:程序能自动生成小学四则运算题目,除了整数以外,还能支持真分数的四则运算。参考链接 http://www.cnblogs.com/jiel/p/4810756.html
设计思想:
- 算术表达式为 e := n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e) , 其中e, e1和e2为表达式,n为自然数或真分数
- 设计思路
- 可将算式等价于 e = [num1 (a) num2] (b) [num3 (c) num4]
- 其中 num1, num2, num3, num4 为运算数,随机取整数或真分数; a, b, c 为运算符号
- 等式的body大小主要取决于a, b, c 的值,用数组定义运算符取值如下:
-
char ysf[5] = {'+', '-', '*', '%', NULL };
当 b 取NULL时,算式变换为 e = [num1 (a) num2] (c) num4
当 c 取NULL时,算式变换为 e = [num1 (a) num2] (b) num3
以此类推,但要求 a 不能为NULL。
4. 形成初期代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 #include<iostream> 5 #define random(x) (rand()%(x)) 6 using namespace std; 7 int main() 8 { 9 int num1 = 0, num2 = 0, num3 = 0, num4 = 0; 10 int a = 0, b = 0, c = 0; 11 char ysf[5] = {'+', '-', '*', '%', NULL }; 12 time_t t; 13 srand((unsigned)time(&t)); //重置随机数种子 14 int n; 15 cin >> n ; 16 for (int i = 1; i <= n; i++) // 生成n道题 17 { 18 do // a运算符不为NULL 19 { 20 a = random(5); 21 } while (a == 4); 22 23 b = random(5); 24 c = random(5); 25 26 if (b == 4 && c != 4 ) 27 { 28 cout << "(" << num1 << ' ' << ysf[a] << ' ' << num2 << ")" << ' ' << ysf[c] << ' ' << num4<< ' ' << '='<< ' ' << endl; 29 } 30 else if (b != 4 && c == 4) 31 { 32 cout << "(" << num1 << ' ' << ysf[a] << ' ' << num2 << ")" << ' ' << ysf[b] << ' ' << num3 << ' ' << '=' << ' ' << endl; 33 } 34 else if (b != 4 && c != 4) 35 { 36 cout << "(" << num1 << ' ' << ysf[a] << ' ' << num2 << ")" << ' ' << ysf[b] << ' ' << "(" << num3 << ' ' << ysf[c] << ' ' << num4 << ")" << ' ' << '=' << ' ' << endl; 37 } 38 else 39 { 40 cout <<num1 << ' ' << ysf[a] << ' ' << num2 << ' ' << '=' << ' ' << endl; 41 } 42 43 } 44 return 0; 45 }
运行截图:
设计完善:
- 完善num(1...4)能随机产生整数或分数
- 分数的分子与分母不为0
- 如果分数的分子大于分母,则对调分子和分母的值
- 将算式放进数组 e[100] 里面,单字符的运算符将其转换为数组格式,再用strcat函数放进e里面
- 完善后的程序代码:
1 #define _CRT_SECURE_NO_DEPRECATE 1 2 #define _CRT_NONSTDC_NO_DEPRECATE 1 3 4 #include <stdio.h> 5 #include<stdlib.h> 6 #include<time.h> 7 #include<iostream> 8 #include<string> 9 10 char randnum1(int r); //随机生成num,如果是分数,转为random2 11 char random2(int r); //随机生成分数形式的num 12 char * zhuanhuan(int i); // 单字符符号转为数组 13 int input(int r); // 插入等式e 14 int reset(); 15 16 char e[100]; //定义全局变量 数组e存放等式 17 18 #define random(x) (rand()%(x)) 19 using namespace std; 20 int a = 0, b = 0, c = 0; 21 char ysf[5] = { '+', '-', '*', '%', NULL }; 22 int main() 23 { 24 time_t t; 25 srand((unsigned)time(&t)); //重置随机数种子 26 int n,r; //n 参数控制生成题目的个数, r 参数控制题目中数值范围 27 cout << "请输入 n (题数),和 r (数值范围)的值: "; 28 cin >> n >> r ; 29 cout <<"\n"; 30 for (int i = 1; i <= n; i++) // 生成n道题 31 { 32 do // a运算符不为NULL 33 { 34 a = random(5); 35 } while (a == 4); 36 37 b = random(5); 38 c = random(5); 39 40 input(r); 41 cout << e << endl; 42 cout << "\n"; 43 reset(); 44 } 45 return 0; 46 } 47 48 int input(int r) 49 { 50 if (b != 4 || c != 4) 51 { 52 strcat(e, "("); 53 randnum1(r); //插入num1 54 strcat(e, " "); 55 strcat(e, zhuanhuan(a)); 56 strcat(e, " "); 57 randnum1(r); //插入num2 58 strcat(e, ")"); 59 if (b == 4 && c != 4) 60 { 61 strcat(e, " "); 62 strcat(e, zhuanhuan(c)); 63 strcat(e, " "); 64 randnum1(r); //插入num4 65 strcat(e, " "); 66 strcat(e, "="); 67 strcat(e, " "); 68 } 69 else if (b != 4 && c == 4) 70 { 71 strcat(e, " "); 72 strcat(e, zhuanhuan(b)); 73 strcat(e, " "); 74 randnum1(r); 75 strcat(e, " "); 76 strcat(e, "="); 77 strcat(e, " "); 78 } 79 else 80 { 81 strcat(e, " "); 82 strcat(e, zhuanhuan(b)); 83 strcat(e, " "); 84 strcat(e, "("); 85 randnum1(r); //插入num3 86 strcat(e, " "); 87 strcat(e, zhuanhuan(c)); 88 strcat(e, " "); 89 randnum1(r); //插入num4 90 strcat(e, ")"); 91 strcat(e, " "); 92 strcat(e, "="); 93 strcat(e, " "); 94 } 95 } 96 else 97 { 98 randnum1(r); //插入num1 99 strcat(e, " "); 100 strcat(e, zhuanhuan(a)); 101 strcat(e, " "); 102 randnum1(r); //插入num2 103 strcat(e, " "); 104 strcat(e, "="); 105 strcat(e, " "); 106 } 107 108 return 0; 109 } 110 111 char randnum1(int r) //对数进行随机 112 { 113 int t = 0; 114 t = random(2); //对临时变量t随机,结果为0,这个数为整数,结果为1则为分数 115 if (t == 0) 116 { 117 int num; 118 do 119 { 120 num = random(r + 1); 121 } while (num == 0); // 随机整数不为 0 122 123 char buf[10]; 124 itoa(num, buf, 10); //将整数转换char类型存储buf中 125 strcat(e, buf); //插入e 126 } 127 else 128 { 129 random2(r); 130 } 131 return 0; 132 } 133 134 char random2(int r) //分数随机 135 { 136 137 int x, y; //x为分子,y为分母 138 do 139 { 140 x = random(r + 1); 141 } while (x == 0); //分子不为0 142 do 143 { 144 y = random(r + 1); 145 } while (y == 0 || y == x); //分母不为0,且不等于分子 146 147 if (x > y) //如果分子比分母大,则对调分子分母位置 148 { 149 int t = x; 150 x = y; 151 y = t; 152 } 153 char bufx[10]; 154 char bufy[10]; 155 itoa(x, bufx, 10); 156 itoa(y, bufy, 10); 157 strcat(e, bufx); 158 strcat(e, "/"); 159 strcat(e, bufy); 160 return 0; 161 } 162 163 char * zhuanhuan(int i) // 单字符符号转为数组 164 { 165 char *m = (char *)malloc(sizeof(char) * 2); 166 m[0] = ysf[i]; 167 m[1] = '\0'; 168 return m; 169 } 170 171 int reset() //将数组e清零 172 { 173 for (int i = 0; i < 100;i++) 174 { 175 e[i] = 0; 176 } 177 return 0; 178 }
程序执行截图(Visual Studio 2015):
尚需完善:1. 减号左边需大于右边; 2.同等级符号可去括号
编写程序时出现的问题:由于无法将符号位用strcat直接插入数组,所以需要进行转换
strcat(e, ysf[a]); //程序报错 //正确方法: char *m = (char *)malloc(sizeof(char) * 2); m[0] = ysf[a]; m[1] = '\0'; strcat(e, m);
鸣谢 @冯老师 & @助教老师们