二柱子四则运算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 //二柱子牌出题器——四则运算生成