题目要求:在第一次原有的功能的基础上增加以下功能:
1.避免题目的重复
2.可定制(可定制题目数量\打印方式)
3.控制参数的生成:
a.是否允许乘除发的生成
b.是否允许有括号的生成(最多支持十个数参与运算)
c.可以设定数值范围的范围
d.是否负数参与运算
e.除法是否有余数
我的代码:
1 #include<iostream> 2 #include<ctime> 3 #include<strstream> 4 #include<stdlib.h> 5 #include<string> 6 #include<vector> 7 #define random(l,h) (rand()%(h-l+1)+l)//宏定义 8 using namespace std; 9 int flag = 1;//全局变量, 10 11 int suiji(int down,int up)//随机生成1至n的整数 12 { 13 int low = down, high = up; 14 if (flag) 15 { 16 flag = 0; 17 srand((unsigned)time(NULL));//种子 18 } 19 //random = rand() % (high - low + 1) + low;//生成随机数 20 int result=random(down, up); 21 return result; 22 23 } 24 int max(int a, int b)//返回两个整数中较大的整数 25 { 26 int h = a >= b ? a : b; 27 return h; 28 } 29 int min(int a, int b)//返回两个整数中较小的整数 30 { 31 int l = a <= b ? a : b; 32 return l; 33 } 34 string fraction(int d,int u)//生成真分数 35 { 36 int temp1 = suiji(d,u);//调用function函数随机生成两个随机整数 37 int temp2 = suiji(d,u); 38 int high = min(temp1, temp2);//比较两个整数的大小,其中较大的整数做分母,较小的整数做分子 39 int low = max(temp1, temp2); 40 strstream tra, ss;//将分子分母从int型转换为string型 41 string up, down; 42 tra << high; 43 tra >> up; 44 ss << low; 45 ss >> down; 46 string fra; 47 high != low ? fra = up + "\\" + down : fra = "1";//将分子分母连接成真分数 48 return fra; 49 } 50 bool is_unique(string str, vector <string> s)//判断生成的运算式是否重复 51 { 52 int count = 0; 53 for (int i = 0;i < s.size();i++) 54 { 55 if (str != s[i]) 56 { 57 count++; 58 } 59 else break; 60 } 61 bool flag0 = count == s.size() ? true : false; 62 return flag0; 63 } 64 void yunsuan(int time,int low,int high,int fl1,int fl2,int fl3,int fl4,int fl5)//根据参数要求生成四则运算式 65 { 66 int integer1, integer2; 67 int ch1, ch2, ch3,ch4;//switch语句的选项 68 //int j=1,i=0; 69 char sign;//运算符号 70 int times = time;//题目数 71 vector <string> str;//str用来保存生成的题目 72 for (int i = 1;i <= times;) 73 { 74 int flag4 = 1;//flag4用来标记运算式是否是刚开始生成 75 string first, second, cal ;//四则运算的第一个运算数和第二个运算数 76 int number = suiji(1, 9);//number为参与运算的参数个数 77 for (int j = 1;j <= number;) 78 { 79 //------------------------------------------------------------------------------------- 80 if (fl1 == 1)//允许乘除发参与运算的情况 81 { 82 ch1 = suiji(1, 4);//随机生成运算符号 83 switch (ch1) 84 { 85 case 1:sign = ‘+‘;break; 86 case 2:sign = ‘-‘;break; 87 case 3:sign = ‘*‘;break; 88 case 4:sign = ‘/‘;break; 89 default:cout << "有错误!" << endl;break; 90 } 91 } 92 else//不允许乘除法参与运算的情况 93 { 94 ch1 = suiji(1, 2);//随机生成运算符号 95 switch (ch1) 96 { 97 case 1:sign = ‘+‘;break; 98 case 2:sign = ‘-‘;break; 99 default:cout << "有错误!" << endl;break; 100 } 101 } 102 //------------------------------------------------------------------------------------- 103 if (fl4 == 1)//允许真分数参与运算 104 { 105 ch2 = suiji(1, 3);//四则运算题目的三种情况 106 switch (ch2) 107 { 108 case 1://整数和整数 109 { 110 strstream ss, cc; 111 integer1 = suiji(low, high); 112 ss << integer1;//将int型变量转换为string型变量 113 ss >> first; 114 integer2 = suiji(low, high); 115 cc << integer2; 116 cc >> second; 117 }break; 118 case 2://整数和真分数 119 { 120 strstream kk; 121 integer1 = suiji(low, high); 122 kk << integer1; 123 kk >> first; 124 second = fraction(low, high); 125 }break; 126 case 3://真分数和真分数 127 { 128 first = fraction(low, high); 129 second = fraction(low, high); 130 }break; 131 default:cout << "有错误!" << endl;break; 132 } 133 } 134 else//不允许真分数参与运算 135 { 136 strstream ss, cc; 137 integer1 = suiji(low, high); 138 ss << integer1;//将int型变量转换为string型的变量 139 ss >> first; 140 integer2 = suiji(low, high); 141 cc << integer2; 142 cc >> second; 143 } 144 //------------------------------------------------------------------------------------- 145 if (fl2 == 1)//允许负数参与运算 146 { 147 ch3 = suiji(1, 3); 148 switch (ch3)//根据随机情况添加负号 149 { 150 case 1:first = "(" + first + ")";second = "(" + second + ")";break; 151 case 2:first = "(-" + first + ")";second = "(" + second + ")";break; 152 case 3:first = "(-" + first + ")";second = "(-" + second + ")";break; 153 } 154 } 155 else//不允许负数参与运算 156 { 157 first = "(" + first + ")"; 158 second = "(" + second + ")"; 159 } 160 161 //------------------------------------------------------------------------------------- 162 if (fl3 == 1)//允许括号(【】)参与运算 163 { 164 ch4 = suiji(1, 4); 165 switch (ch4) 166 { 167 case 1: 168 { 169 if (flag4 == 1)//flag4为1表示运算式还未生成前两个运算数 170 { 171 cal = first + sign + second; 172 flag4 = 0; 173 } 174 else 175 { 176 cal = cal + sign + first;//将以生成的运算式个新生成的运算数连接起来 177 } 178 }break; 179 case 2: 180 { 181 if (flag4 == 1) 182 { 183 cal = second + sign + first; 184 flag4 = 0; 185 } 186 else 187 { 188 cal = second + sign + cal; 189 } 190 }break; 191 case 3: 192 { 193 if (flag4 == 1) 194 { 195 cal = "[" + first + sign + second + "]";//添加括号【】的情况 196 flag4 = 0; 197 } 198 else 199 { 200 cal = "[" + cal + sign + first + "]"; 201 } 202 }break; 203 case 4: 204 { 205 if (flag4 == 1) 206 { 207 cal = "[" + second + sign + first + "]"; 208 flag4 = 0; 209 } 210 else 211 { 212 cal = "[" + second + sign + cal + "]"; 213 } 214 }break; 215 default:cout << "有错误!" << endl;break; 216 } 217 } 218 else//不允许括号(【】)参与运算 219 { 220 ch4 = suiji(1, 2);//输出的两种情况 221 switch (ch4) 222 { 223 case 1: 224 { 225 if (flag4 == 1) 226 { 227 cal = first + sign + second; 228 flag4 = 0; 229 } 230 else 231 { 232 cal = cal + sign + first; 233 } 234 }break; 235 case 2: 236 { 237 if (flag4 == 1) 238 { 239 cal = second + sign + first; 240 flag4 = 0; 241 } 242 else 243 { 244 cal = second + sign + cal; 245 } 246 }break; 247 default:cout << "有错误!" << endl;break; 248 } 249 } 250 j++; 251 } 252 //------------------------------------------------------------------------------ 253 if (str.empty())//若sr为空,则将第一个生成的运算式添加到vector中 254 { 255 str.push_back(cal); 256 cout << "(" << i << ")." << cal << "=" << endl; 257 i++; 258 } 259 if (is_unique(cal, str))//判断生成的运算式和之前已经生成的运算式是否重复 260 { 261 str.push_back(cal);//将生成的运算式添加到str中 262 cout << "(" << i << ")." << cal << "=" << endl; 263 i++; 264 } 265 else {} 266 } 267 } 268 int main() 269 { 270 cout << "请输入题目数(1~100):"; 271 int times,down,up,flag1,flag2,flag3,flag4,flag5=1; 272 cin >> times;//times至题目数 273 cout << "请输入数值绝对值范围:"; 274 cin >> down >> up;//[down,up]为运算数范围 275 cout << "是否允许乘除发参与运算(y/n):"; 276 char yn1; 277 cin >> yn1; 278 yn1 == ‘y‘ || yn1==‘Y‘ ? flag1 = 1 : flag1 = 0; 279 cout << "是否允许负数参与运算(y/n):";//flag1判断是否允许乘除法参与运算 280 char yn; 281 cin >> yn; 282 yn == ‘y‘||yn==‘Y‘ ? flag2 = 1 : flag2 = 0;//flag2判断是否允许负数 283 cout << "是否允许括号([])参与运算(y/n):"; 284 char yn2; 285 cin >> yn2; 286 yn2 == ‘y‘||yn2==‘Y‘ ? flag3 = 1 : flag3 = 0;//flag3判断是否允许括号参与运算 287 cout << "是否允许真分数参与运算(y/n):"; 288 char yn3; 289 cin >> yn3; 290 yn3 == ‘y‘||yn3==‘Y‘ ? flag4 = 1 : flag4 = 0;//flag4判断是否允许真分数参与运算 291 yunsuan(times,down,up,flag1,flag2,flag3,flag4,flag5); 292 system("pause"); 293 return 0; 294 }
生成的结果:
结果1:
结果2:
结果3:
结果5:
结果5:
设计思路:
1.避免题目的重复:本题利用了vector<string> str,先判断str是否为空:若为空则代表生成的运算式是第一个,此时将生成的运算式添加到str中,然后将运算式输出即可;若不为空,则调用is_unique()函数(此函数将生成的运算式与str中的所有元素进行比较来判断生成的运算式是否与之前的运算式重复),若返回true,则将运算式输出
2.可定制:本题目中要求运算式中的运算数数目随机但不可以超过10个,为此我设置了一个局部变量number,并随机生成一个10以内的随机数赋值与number来表示运算式中运算数的数目
3.参数设:本题中我设置里5个flag变量来判断相关设置条件是否满足,然后利用if-else语句根据flag的值进行相关运算式的生成
缺陷:
本题可以用递归的思想结局,但本人还是利用了循环和switch语句的结合解决这个问题,相对来说代码相对比较冗长;其次由于跟人能力的限制,本题中最后一个功能没有实现,我原想利用栈来解决这个问题,但这里面还涉及到真分数的除法运算,着实有些复杂,所以暂时我还没有什么好得方法可以解决,我会继续思考这个功能的解决方案,并在第一时间将我的解决方案公布