四则运算题目生成器2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算题目生成器2相关的知识,希望对你有一定的参考价值。

题目要求:在第一次原有的功能的基础上增加以下功能:

            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语句的结合解决这个问题,相对来说代码相对比较冗长;其次由于跟人能力的限制,本题中最后一个功能没有实现,我原想利用栈来解决这个问题,但这里面还涉及到真分数的除法运算,着实有些复杂,所以暂时我还没有什么好得方法可以解决,我会继续思考这个功能的解决方案,并在第一时间将我的解决方案公布

 

以上是关于四则运算题目生成器2的主要内容,如果未能解决你的问题,请参考以下文章

第一次作业-自动生成四则运算的题目

实现自动生成30道四则运算题目

自动生成四则运算题目程序

第一次作业-四则运算题目生成程序

个人作业-四则运算题目生成程序(基于控制台)

c/c++:四则运算题目生成器3