二柱子四则运算3

Posted 波棱盖儿卡秃噜皮

tags:

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

二柱子四则运算3

可怜的二柱子……又一次被坑了……

老师又在上次的“二柱子四则运算2”的基础上增添了要求,如下:

1、学生写的程序必须能判定用户的输入答案是否正确。直到题目结束,告诉用户做对了几道题。

2、程序必须能处理四种运算的混合模式。

注意:连续的减法和除法,应该遵守左结合的规定。

        连续除法要打括号,否则会引起歧义。


一、实验思路

      这次的实验是结对开发的项目第一次,我的合作小伙伴是孔宇航孔同学,说实话这是我俩第一次合作,因此各方面都还需要磨合和适应,不过总体来说分工合作明确,效果还算可以~鉴于我们编程能力和逻辑思维方式的差异,最后决定由我来执行编写程序,她来把握总体流程、分析并设计算法并适当的查阅相关的资料。   

      关于这次实验,由于上次实验我的思维有点混乱,写出的代码老师说重复率太高,而她的代码也是很多功能没有实现,所以我们决定重新静下心来编写代码。这次我们延续上次的思想,将很多内容封装到函数里,包括:“选择打印方式”、“判断输入的01菜单是否正确”、“生成某一个范围内的随机数”、“生成随机的分数”、“生成一个运算符”、“判断整数的正负并取相反数”、“把int类型装换为string类型”、以及“含有括号的运算”、“含有真分数的运算”和“不含真分数的运算”等等。运行程序时用户先选择相关的参数定制:题目个数、数值范围、是否打印到文件里、是否含有括号、加减或者四则运算等等。

部分函数的思路和功能:

1、  生成一个随机运算符:

      根据从主函数读取到的用户的选择:是否包含乘除运算来随机生成0-3四个数字分别代表+-*/四则运算,并将其作为函数的返回值。单独列出这个函数的目的是防止出现像上次的程序一样分析switch语句的四种情况时代码冗余而导致思维混乱。

2、  把int类型转换为string:

      经过我们查阅资料,决定使用:#include<stdio.h>类库中的str=itoa(shu, zhuan, 10)函数来将生成的随机整数保存成string字符串的形式。

编写此函数是因为,所有的算式都是用string字符串存的,方便输出和查重,因此每一个操作符都要转换成string才能直接插到算式中。

3、  生成某一个范围内的真分数:

      通过判断分子小于分母(真分数)、分子分母没有公约数(最简分式)产生那个数:分子和分母的值,再通过随机生成正负号来决定分数值的正负,最后将符号、分子、分数线和分母写到一个string类型里,并将分数形式和分数的值返回。

4、  查重:

      查重的函数上次的实验中有一些问题,因为是使用int类型的二维数组存的因此不能查关于真分数的重复,而这次采用string类型数组的方法,将所有的算式依次存到string类型的数组中,然后逐个比较新生成的算式与其是否相等。如果相等就舍掉相应的式子,并且计数的值-1。

5、  关于含有真分数和不含有真分数的计算:

      就是调用以上各个函数,再根据用户选择的是否含有负数、除法有无余数等等进行选择和判断,但是要将结果保存下来,便于判断是否回答正确。

6、  含有括号的计算:

      这个我们讨论了很久……也阅读了很多资料和同学们的代码,有了基本的思路,但是在我编写代码实现的过程中发现思路还存在漏洞,根本进行不下去了。今天的时间有限,对于两个星期还是没有研究出这个算法的我也是十分懊恼的……我发誓,下周有时间我一定要把含有括号的式子写出来,一定!!!!!!!

      但是我们编写的含有括号的函数我没有删掉,附在了实验源码里。思路如下:

      我们打算用“递归”的思想先随机生成一个二元运算的式子,当然这里的操作数和运算符都是随机生成的,然后用double类型变量记录算式的值,然后随机生成加不加括号、并且下一个运算符是加在前面还是后面。然后将生成的式子再作为二元运算的操作数,直到随机生成的是不加括号,则输出式子。

7、  主函数:

      本次实验最大的差异就是要用户计算结果、系统判断是否回答正确并记录正确的题目数。一次我们的函数中只是返回一个算式和算式的值,在主函数中循环N次,每一次输出就让用户输入,并判断是否正确。算式是用string类型存放,算式的值用double类型存放,如果答案是整数,直接让用户输入一个整数;如果答案是小数,先输入int型分子,再输入分母,并强制转换double计算结果。判断对错时,设定一个精度(10的负7次方),如果用户的输入在此范围内则认定正确。

    (PS.在这里我不得不说,我们本来打算接收用户输入的string类型的值(可以直接输入分数),这就要用ASC码分离出分子分母和分数线。最后我们还是输给了时间……┑( ̄Д  ̄)┍唉……)

二、实验源代码

 实验的源代码如下:

  1 //二柱子四则运算3,2016/3/14,赵子茵&孔宇航
  2 
  3 #include<iostream>
  4 #include<time.h>
  5 #include<stdlib.h>
  6 #include<stdio.h>
  7 #include<string>
  8 #include<fstream>
  9 #include<iomanip>
 10 #include<cmath> 
 11 #define random(x) (rand()%x)
 12 using namespace std;
 13 
 14 /*选择打印方式*/
 15 void Output(int sf)
 16 {
 17     if (sf == 1)//保存文档
 18     {
 19         ofstream outfile("formula.txt", ios::out);
 20         if (!outfile)
 21         {
 22             cout << "Open error!!" << endl;
 23             exit(1);
 24         }
 25         outfile << "----------------欢迎!小学生四则运算答题系统:-D----------------" << endl;
 26         outfile.close();
 27     }
 28 }
 29 
 30 /*判断输入0.1的是否输入正确*/
 31 int Istrue_input(int mnu01)
 32 {
 33     while (1)
 34     {
 35         if (mnu01 != 0 && mnu01 != 1)
 36         {
 37             cout << "输入有误,请重新输入(请输入0或1):" << endl;
 38             cin >> mnu01;
 39         }
 40         else
 41             break;
 42     }
 43     return mnu01;
 44 }
 45 
 46 /*生成一个某范围内的随机数(正负都有)*/
 47 int Creat_random(int r1, int r2)
 48 {
 49     int r, shu;
 50     /*srand((int)time(0));*/
 51     r = r2 - r1;
 52     shu = r1 + rand() % r;
 53     return shu;
 54 }
 55 
 56 /*生成一个随机运算符*/
 57 string Create_oper(int lai)
 58 {
 59     srand((int)time(0));
 60     string sign;
 61     int Num_sym, Sign_num;
 62     if (lai == 0)//加减
 63         Num_sym = 2;
 64     else if (lai == 1)//加减乘除
 65         Num_sym = 4;
 66     Sign_num = rand() % Num_sym;//生成随机的数字代表运算符
 67     switch (Sign_num)
 68     {
 69     case(0) : sign = \'+\'; break;
 70     case(1) : sign = \'-\'; break;
 71     case(2) : sign = \'*\'; break;
 72     case(3) : sign = \'/\'; break;
 73     }
 74     return sign;
 75 }
 76 
 77 /*判断整数正负并取相反数*/
 78 int Opp_zf(int a)
 79 {
 80     if (a < 0)
 81         a = -a;
 82     return a;
 83 }
 84 
 85 /*把int类型转换为string类型*/
 86 string Int_str(int shu)
 87 {
 88     char zhuan[100];
 89     string str,zuo="(",you=")";
 90     str=itoa(shu, zhuan, 10);
 91     if (shu < 0)
 92         str = zuo + str + you;
 93     return str;
 94 }
 95 
 96 /*生成一个(某范围)真分数*/
 97 void Creat_fen(int r1, int r2, string &fenshu, double &zhi)
 98 {
 99     /*srand((int)time(0));*/
100     int i, r = r2 - r1, up, down, s;
101     bool flag;
102     string xian = "/", fu = "-", zuo = "(", you = ")";
103     /*char zhuan1[10], zhuan2[10];*/
104     string zhuan1, zhuan2;
105 loop:do
106     {
107          flag = false;//不能定义全局变量!!
108          up = r1 + rand() % r;
109          up = Opp_zf(up);
110          down = r1 + rand() % r;
111          down = Opp_zf(down);
112     } while ((up >= down) || (down == 0) || (up == 0));//分子≥分母 or 分母=0 or 分子=0 重新生成
113     
114     for (i = 2; i <= up; i++)
115     {
116         /*if ((i == -1)|| (i == 0))
117         continue;*/
118         if (up%i == 0 && down%i == 0)
119         {
120             flag = true;//有公约数    
121             break;
122         }
123     }
124     if (flag == true)
125     {
126         goto loop;
127     }
128     else
129     {
130         zhi = (double)up / (double)down;
131         //itoa(up, zhuan1, 10);//分子转换成string类型
132         //itoa(down, zhuan2, 10);//分母转换成string类型
133         zhuan1 = Int_str(up);//up/down都是正数不会再加一层括号
134         zhuan2 = Int_str(down);
135         s = rand() % 2;
136         switch (s)
137         {
138             //正分数
139             case(0) : 
140                 fenshu = zuo + zhuan1 + xian + zhuan2 + you; 
141                 break;
142             //负分数
143             case(1) : 
144                 fenshu = zuo + fu + zhuan1 + xian + zhuan2 + you;
145                 zhi = -zhi;
146                 break;
147         }
148     }
149     //return fenshu;
150 }
151 
152 ///*查重*/
153 //bool Is_rept(string str1, string str2)
154 //{
155 //    if (str1 == str2)
156 //        return true;//重复
157 //    return false;//不重复
158 //}
159 
160 /*含有括号*/
161 void Have_kuohao(int r1, int r2, string &formula,double &zhi)
162 {
163     srand((int)time(0));
164     int op,op1, op2;
165     int yn, qh;//代表“是否加括号”和“运算符在前后”的数字
166     string symbol1,symbol2;
167     string zhuan,zhuan1, zhuan2;
168     string jia = "+", jian = "-", cheng = "*", chu = "/",zuo="(",you=")";
169 
170     zhi = (double)Creat_random(r1, r2);
171     op1 = Creat_random(r1, r2);
172     op2 = Creat_random(r1, r2);
173     op = Creat_random(r1, r2);//假设op2做分母不能为0
174     while (1)
175     {
176         if (op == 0)
177             op = Creat_random(r1, r2);
178         else
179             break;
180     }
181     zhuan1 = Int_str(zhi);
182     zhuan2 = Int_str(op);
183     symbol1 = Create_oper(1);
184 
185     if (symbol1 == "+")
186     {
187         zhi = (double)op1 + (double)op2;
188         formula = zhuan1 + jia + zhuan2;
189         yn = rand() % 2;
190         switch (yn)
191         {
192             //外面不加括号
193             case(0) : break;
194             //外面加括号
195             case(1) :
196             {
197                         formula = zuo + formula + you;
198                         qh = rand() % 2;
199                         symbol2 = Create_oper(1);
200                         switch (qh)
201                         {
202                             //加到前面
203                             case(0) :
204                            {
205                                     formula = symbol2 + formula;
206                                     op = Creat_random(r1, r2);
207                                     zhuan = Int_str(op);
208                                     if (symbol2 == "+")
209                                     {
210                                         zhi = (double)op + zhi;
211                                         formula = zhuan + jia + formula;
212                                     }
213                                     else if (symbol2 == "-")
214                                     {
215                                         zhi = (double)op - zhi;
216                                         formula = zhuan + jian + formula;
217                                     }
218                                     else if (symbol2 == "*")
219                                     {
220                                         zhi = (double)op * zhi;
221                                         formula = zhuan + cheng + formula;
222                                     }
223                                     else if (symbol2 == "/")
224                                     {
225                                         if (zhi == 0)//防止出现随机生成的除号后面的值为0;
226                                             break;
227                                         else
228                                         {
229                                             zhi = (double)op / zhi;
230                                             formula = zhuan + chu + formula;
231                                         }    
232                                     }
233                                     break;
234 
235                              }
236                              //加到后面
237                             case(1) :
238                             {
239                                     formula = formula + symbol2;
240                                     op = Creat_random(r1, r2);//防止后面随机产生除号,分母为0
241                                     while (1)
242                                     {
243                                         if (op == 0)
244                                             op = Creat_random(r1, r2);
245                                         else
246                                             break;
247                                     }
248                                     zhuan = Int_str(op);
249                                     if (symbol2 == "+")
250                                     {
251                                         zhi = zhi + (double)op;
252                                         formula = formula + jia + zhuan;
253                                     }
254                                     else if (symbol2 == "-")
255                                     {
256                                         zhi = zhi - (double)op;
257                                         formula = formula + jian + zhuan;
258                                     }
259                                     else if (symbol2 == "*")
260                                     {
261                                         zhi = zhi * (double)op;
262                                         formula = formula + cheng + zhuan;
263                                     }
264                                     else if (symbol2 == "/")
265                                     {
266                                         zhi = zhi / (double)op;
267                                         formula = formula + chu + zhuan;
268                                     }
269                                     break;
270                               }
271 
272                         }
273                         break;
274             }
275                 
276                 
277         }
278         
279         
280     }
281     else if (symbol1 == "-")
282     {
283         zhi = (double)op1 - (double)op2;
284         formula = zhuan1 + jian + zhuan2;
285     }
286     else if (symbol1 == "*")
287     {
288         zhi = (double)op1 * (double)op2;
289         formula = zhuan1 + cheng + zhuan2;
290     }
291     else if (symbol1 == "/")
292     {
293         zhi = (double)op1 / (double)op2;
294         formula = zhuan1 + chu + zhuan2;
295     }
296 
297         
298     
299     
300 
301 }
302 
303 /*含有真分数*/
304 void Have_fenshu(int LL, int r1, int r2, string &formula, double &zhi, int jj)
305 {
306     srand((int)time(0));
307     string F1, F2, symbol, zhuan;
308     double Z1, Z2;//
309     int inter, type;
310     inter = Creat_random(r1, r2);//整数
311     zhuan = Int_str(inter);
312     Creat_fen(r1, r2, F1, Z1);//分数1
313     Creat_fen(r1, r2, F2, Z2);//分数2
314     symbol = Create_oper(LL);//符号
315     type = rand() % 3;//类型
316 
317     if (jj == 0)//加减没有负数
318     {
319         inter = Opp_zf(inter);
320         zhuan = Int_str(inter);
321         while (1)
322         {
323             if (Z1 <0)
324                 Creat_fen(r1, r2, F1, Z1);
325             else
326                 break;
327         }
328         while (1)
329         {
330             if (Z2 <0)
331                 Creat_fen(r1, r2, F2, Z2);
332             else
333                 break;
334         }
335     }
336 
337     switch (type)
338     {
339         //二柱子牌出题器——四则运算生成

二柱子四则运算在线答题系统

二柱子四则运算3

二柱子四则运算定制版+升级版

二柱子的三个阶段——随机生成四则运算题目(java语言版)

二柱子之随机四则运算