第二次程序+PSP0级
第二周,老师接着上次的程序有对四则运算的程序,做出来一些要求,这次要求可以控制乘除法,有无括号,控制输出方式,控制结果有无负数,有无余数。
我在对原先的程序分析了一下,发现我原先的程序可扩展性特别差,完全不能再原先的基础上叠加功能,所以我又重新写了一个程序。
思路分析:
1、控制乘除法
2、括号添加。思路:题中只要求添加括号,所以我的括号添加方法是:把所有数放入一个数组中,‘+-*/’都用数字化表示,使用随机函数实现随机选择在哪个运算符左边加上左括号,右括号统一加在右边,其中括号最多只有2层嵌套。
3、判断重复:先生成所有运算式子,然后使用循环判断有无重复。
4、结果有无负数和余数:没任何技巧使用循环里面在加循环,先找到最里面的括号,先乘除再加减,然后消括号重复加减最后得出结果,根据最后结果得出结果。
5、输出方式:使用fstream类把结果输出到1.txt中
1 #include<iostream> 2 #include"time.h" 3 #include<fstream> 4 #define SUM 1000 5 #define SUMS 300 6 using namespace std; 7 int Results[SUM][SUMS] = { 0 }; 8 9 10 void Input(int &base, int &top){ 11 cout << "\n请输入下限(正数) "; 12 cin >> base; 13 cout << "\n请输入上限(正数) "; 14 cin >> top; 15 } 16 //生成四则运算公式 17 void Combination1(int time, int base,int top,int add,int dec,int mul,int div,int equ){ 18 int choose; 19 int amount; 20 amount = 2 + rand() % 9; 21 Results[time][0] = 1 + rand() % top; 22 while (Results[time][0] <= base){ 23 Results[time][0] = 1 + rand() % top; 24 } 25 amount--; 26 int count = 1; 27 while (true){ 28 choose = 1 + rand() % 4; 29 if (choose == 1){ 30 Results[time][count] = add; 31 } 32 if (choose == 2){ 33 Results[time][count] = dec; 34 } 35 if (choose == 3){ 36 Results[time][count] = mul; 37 } 38 if (choose == 4){ 39 Results[time][count] = div; 40 } 41 count++; 42 Results[time][count] = 1 + rand() % top; 43 while (Results[time][count] <= base){ 44 Results[time][count] = 1 + rand() % top; 45 } 46 count++; 47 amount--; 48 if (amount == 0){ 49 break; 50 } 51 } 52 Results[time][count] = equ; 53 54 } 55 //生成二则运算公式 56 void Combination2(int time, int base, int top, int add, int dec, int mul, int div, int equ){ 57 int choose; 58 int amount; 59 amount = 2 + rand() % 9; 60 Results[time][0] = 1 + rand() % top; 61 while (Results[time][0] <= base){ 62 Results[time][0] = 1 + rand() % top; 63 } 64 amount--; 65 int count = 1; 66 while (true){ 67 choose = 1 + rand() % 2; 68 if (choose == 1){ 69 Results[time][count] = add; 70 } 71 if (choose == 2){ 72 Results[time][count] = dec; 73 } 74 count++; 75 Results[time][count] = 1 + rand() % top; 76 while (Results[time][count] <= base){ 77 Results[time][count] = 1 + rand() % top; 78 } 79 count++; 80 amount--; 81 if (amount == 0){ 82 break; 83 } 84 } 85 Results[time][count] = equ; 86 } 87 //cmd 88 void Output(int time, int top,int add, int dec, int mul, int div, int equ,int LBra,int RBra){ 89 int count = 0; 90 while (true){ 91 if (Results[time][count] <= top){ 92 cout << Results[time][count]; 93 } 94 if (Results[time][count] == add){ 95 cout << "+"; 96 } 97 if (Results[time][count] == dec){ 98 cout << "-"; 99 } 100 if (Results[time][count] == mul){ 101 cout << "*"; 102 } 103 if (Results[time][count] == div){ 104 cout << "/"; 105 } 106 if (Results[time][count] == LBra){ 107 cout << "("; 108 } 109 if (Results[time][count] == RBra){ 110 cout << ")"; 111 } 112 if (Results[time][count] == equ){ 113 cout << "="; 114 break; 115 } 116 count++; 117 } 118 } 119 //文件流 120 void OutputFile(int time, int top, int add, int dec, int mul, int div, int equ, int LBra, int RBra){ 121 ofstream out("1.txt", ios::out); 122 int count; 123 for (int i = 0; i < time; i++){ 124 count = 0; 125 while (true){ 126 127 if (Results[i][count] <= top){ 128 out << Results[i][count]; 129 } 130 if (Results[i][count] == add){ 131 out << "+"; 132 } 133 if (Results[i][count] == dec){ 134 out << "-"; 135 } 136 if (Results[i][count] == mul){ 137 out << "*"; 138 } 139 if (Results[i][count] == div){ 140 out << "/"; 141 } 142 if (Results[i][count] == LBra){ 143 out << "("; 144 } 145 if (Results[i][count] == RBra){ 146 out << ")"; 147 } 148 if (Results[i][count] == equ){ 149 out << "="; 150 break; 151 152 } 153 count++; 154 } 155 out << endl; 156 } 157 out.close(); 158 159 } 160 //添加括号 161 void AddBrackets(int time, int add, int dec, int mul, int div, int equ, int LBra,int RBra){ 162 int place; 163 int level=0; 164 int sumNum,sumNum1; 165 int count; 166 int BracketNum; 167 BracketNum = 1 + rand() % 2; 168 for (int i = 0; i < SUMS; i++){ 169 if (Results[time][i] >= add&&Results[time][i] <= div){ 170 level++; 171 } 172 if (Results[time][i] == equ){ 173 sumNum = i; 174 break; 175 } 176 } 177 int BracketNum1; 178 BracketNum1 = BracketNum; 179 //随机在运算公式中生成左括号 180 for (int j = 0; j < BracketNum; j++){ 181 sumNum1 = sumNum; 182 if (level == 1){ 183 break; 184 } 185 place = 1 + rand() % (level - 1); 186 count = 0; 187 while (true){ 188 if (Results[time][count] >= add&&Results[time][count] <= div){ 189 place = place - 1; 190 if (place == 0){ 191 break; 192 } 193 } 194 count++; 195 } 196 if (Results[time][count + 1] == LBra){ 197 BracketNum1--; 198 break; 199 } 200 while (true){ 201 Results[time][sumNum + 1] = Results[time][sumNum]; 202 if (sumNum - 1 == count){ 203 Results[time][sumNum] = LBra; 204 break; 205 } 206 sumNum--; 207 } 208 sumNum = sumNum1 + 1; 209 } 210 //直接在等式右边生成相同数量的有括号 211 for (int k = 0; k < BracketNum1; k++){ 212 if (level == 1){ 213 break; 214 } 215 Results[time][sumNum + 1] = Results[time][sumNum]; 216 Results[time][sumNum] = RBra; 217 sumNum++; 218 } 219 if (Results[time][sumNum] != equ){ 220 AddBrackets(time, add, dec, mul, div, equ, LBra, RBra); 221 } 222 sumNum1 = sumNum-1; 223 count = 0; 224 while (true){ 225 if (Results[time][sumNum1] == RBra){ 226 count++; 227 } 228 sumNum1--; 229 if (sumNum1 == sumNum - 3){ 230 break; 231 } 232 } 233 sumNum1 = 0; 234 while (true){ 235 if (Results[time][sumNum1] == LBra){ 236 count--; 237 } 238 if (sumNum1 == sumNum){ 239 break; 240 } 241 sumNum1++; 242 } 243 if (count < 0){ 244 AddBrackets(time, add, dec, mul, div, equ, LBra, RBra); 245 } 246 } 247 //判断有误重复 248 int Replay(){ 249 int i, j,k; 250 int charge; 251 for (i = 0; i < SUM; i++){ 252 charge = 0; 253 for (j = i+1; j < SUM; j++){ 254 for (k = 0; k < SUMS; k++){ 255 if (Results[i][k] != Results[j][k]){ 256 charge = 1; 257 break; 258 } 259 } 260 if (charge == 0){ 261 return 1; 262 } 263 } 264 } 265 return 0; 266 } 267 268 //判断有无余数和是否正数 269 //把公式化成float型,有利于进行判断有无余数,而且计算更准确 270 void Judge(int time, int equ, int add, int dec, int mul, int div, int LBra, int RBra, int &pos, int &integer){ 271 float calculate[SUMS]; 272 int Bracket[2] = { 0 }; //用于记录括号位置 273 int count = 0; 274 int sumNum, sumNum1, sumNum2; 275 for (int i = 0; i < SUMS; i++){ 276 if (Results[time][i] == LBra){ 277 Bracket[count] = i; 278 count++; 279 } 280 if (count == 2){ 281 break; 282 } 283 if (Results[time][i] == RBra){ 284 break; 285 } 286 } 287 for (int i = 0; i < SUMS; i++){ 288 if (Results[time][i] == RBra){ 289 sumNum = i; 290 break; 291 } 292 } 293 for (int i = 0; i < sumNum; i++){ 294 calculate[i] = float(Results[time][i]); 295 } 296 int Has = 0; 297 int place; 298 //双括号 299 if (count == 2){ 300 sumNum1 = Bracket[1]; 301 302 //sumNum2 = sumNum1; 303 while (true){ 304 Has = 0; 305 for (int i = sumNum1 + 1; i < sumNum; i++){ 306 if (calculate[i] == mul) 307 { 308 calculate[i - 1] = calculate[i - 1] * calculate[i + 1]; 309 Has = 1; 310 place = i; 311 break; 312 } 313 if (calculate[i] == div) 314 { 315 calculate[i - 1] = calculate[i - 1] / calculate[i + 1]; 316 Has = 1; 317 place = i; 318 break; 319 } 320 } 321 if (Has == 1){ 322 while (true){ 323 if ((place + 2) == sumNum){ 324 break; 325 } 326 calculate[place] = calculate[place + 2]; 327 place++; 328 329 330 } 331 sumNum -= 2; 332 } 333 if (Has == 0){ 334 break; 335 } 336 } 337 sumNum1 += 1; 338 sumNum2 = sumNum1; 339 while (true){ 340 if (sumNum1 + 1 >= sumNum){ 341 break; 342 } 343 if (calculate[sumNum1 + 1] == add){ 344 calculate[sumNum2] = calculate[sumNum2] + calculate[sumNum1 + 2]; 345 sumNum1 += 2; 346 } 347 if (calculate[sumNum1 + 1] == dec){ 348 calculate[sumNum2] = calculate[sumNum2] - calculate[sumNum1 + 2]; 349 sumNum1 += 2; 350 } 351 } 352 calculate[sumNum2 - 1] = calculate[sumNum2]; 353 sumNum = sumNum2; 354 count = count - 1; 355 } 356 if (count == 1){ //单括号 357 sumNum1 = Bracket[0]; 358 while (true){ 359 Has = 0; 360 for (int i = sumNum1 + 1; i < sumNum; i++){ 361 if (calculate[i] == mul) 362 { 363 calculate[i - 1] = calculate[i - 1] * calculate[i + 1]; 364 Has = 1; 365 place = i; 366 break; 367 } 368 if (calculate[i] == div) 369 { 370 calculate[i - 1] = calculate[i - 1] / calculate[i + 1]; 371 Has = 1; 372 place = i; 373 break; 374 } 375 } 376 if (Has == 1){ 377 while (true){ 378 if ((place + 2) == sumNum){ 379 break; 380 } 381 calculate[place] = calculate[place + 2]; 382 place++; 383 384 385 } 386 sumNum -= 2; 387 } 388 if (Has == 0){ 389 break; 390 } 391 } 392 sumNum1 += 1; 393 sumNum2 = sumNum1; 394 while (true){ 395 if (sumNum1 + 1 >= sumNum){ 396 break; 397 } 398 if (calculate[sumNum1 + 1] == add){ 399 calculate[sumNum2] = calculate[sumNum2] + calculate[sumNum1 + 2]; 400 sumNum1 += 2; 401 } 402 if (calculate[sumNum1 + 1] == dec){ 403 calculate[sumNum2] = calculate[sumNum2] - calculate[sumNum1 + 2]; 404 sumNum1 += 2; 405 } 406 } 407 calculate[sumNum2 - 1] = calculate[sumNum2]; 408 sumNum = sumNum2; 409 } 410 for (int i = 0; i < sumNum; i++){ 411 if (calculate[i] == mul){ 412 calculate[i - 1] *= calculate[i + 1]; 413 place = i; 414 while (true){ 415 if (place + 2 >= sumNum){ 416 sumNum -= 2; 417 break; 418 } 419 calculate[place] = calculate[place + 2]; 420 place += 1; 421 } 422 } 423 if (calculate[i] == div){ 424 calculate[i - 1] /= calculate[i + 1]; 425 place = i; 426 while (true){ 427 428 if (place + 2 >= sumNum){ 429 sumNum -= 2; 430 break; 431 } 432 calculate[place] = calculate[place + 2]; 433 place += 1; 434 } 435 } 436 } 437 for (int i = 0; i < sumNum; i++){ 438 if (calculate[i] == add){ 439 calculate[0] = calculate[0] + calculate[i + 1]; 440 } 441 if (calculate[i] == dec){ 442 calculate[0] = calculate[0] + calculate[i + 1]; 443 } 444 } 445 //结果判断 446 if (calculate[0] >= 0){ 447 pos = 1; 448 } 449 else{ 450 pos = 0; 451 } 452 if ((calculate[0]-int(calculate[0]))!=0) 453 { 454 integer = 0; 455 } 456 else{ 457 integer = 1; 458 } 459 460 } 461 int main(){ 462 srand((unsigned)time(NULL)); 463 int add; 464 int dec; 465 int mul; 466 int div; 467 int equ; 468 int base; 469 int top; 470 int LBra; 471 int RBra; 472 int MulAndDiv; 473 int HaveBracket; 474 int AboveZero; 475 int Isint; 476 int Isrepeat; 477 int Isfile; 478 int sum; 479 int integer; 480 int pos; 481 cout << "是否使用乘除?1表示是,0表示不是: "; 482 cin >> MulAndDiv; 483 cout << "\n是否有括号?1表示是,0表示不是: "; 484 cin >> HaveBracket; 485 cout << "\n结果能否有负数?1表示能,0表示不能: "; 486 cin >> AboveZero; 487 cout << "\n结果能否有余数? 1表示能,0表示不能: "; 488 cin >> Isint; 489 cout << "请输入题目数量:"; 490 cin >> sum; 491 cout << "是否输出到文件? 1表示是,0表示否: "; 492 cin >> Isfile; 493 Input(base, top); 494 add = top + 1; 495 dec = top + 2; 496 mul = top + 3; 497 div = top + 4; 498 equ = top + 5; 499 LBra = top + 6; 500 RBra = top + 7; 501 //判断乘除和有无括号 502 for (int j = 0; j < sum; j++){ 503 if (MulAndDiv == 0){ 504 Combination2(j, base, top, add, dec, mul, div, equ); 505 } 506 else 507 Combination1(j, base, top, add, dec, mul, div, equ); 508 if (HaveBracket == 1){ 509 AddBrackets(j, add, dec, mul, div, equ, LBra, RBra); 510 } 511 512 } 513 //判断有无负数和余数 514 for (int j = 0; j < sum; j++){ 515 pos = 0; 516 integer = 0; 517 Judge(j, equ, add, dec, mul, div, LBra, RBra, pos, integer); 518 if (Isint == 0){ 519 while (integer == 0){ 520 if (MulAndDiv == 0){ 521 Combination2(j, base, top, add, dec, mul, div, equ); 522 } 523 else 524 Combination1(j, base, top, add, dec, mul, div, equ); 525 if (HaveBracket == 1){ 526 AddBrackets(j, add, dec, mul, div, equ, LBra, RBra); 527 } 528 Judge(j, equ, add, dec, mul, div, LBra, RBra, pos, integer); 529 } 530 } 531 if (AboveZero == 0){ 532 while (pos == 0){ 533 if (MulAndDiv == 0){ 534 Combination2(j, base, top, add, dec, mul, div, equ); 535 } 536 else 537 Combination1(j, base, top, add, dec, mul, div, equ); 538 if (HaveBracket == 1){ 539 AddBrackets(j, add, dec, mul, div, equ, LBra, RBra); 540 } 541 Judge(j, equ, add, dec, mul, div, LBra, RBra, pos, integer); 542 } 543 } 544 } 545 //查重 546 while(true){ 547 if (Replay() == 1){ 548 if (Isfile == 1){ 549 OutputFile(sum, top, add, dec, mul, div, equ, LBra, RBra); 550 } 551 else{ 552 for (int j = 0; j < sum; j++){ 553 Output(j, top, add, dec, mul, div, equ, LBra, RBra); 554 cout << endl; 555 } 556 } 557 break; 558 } 559 else 560 { 561 for (int j = 0; j < sum; j++){ 562 if (MulAndDiv == 0){ 563 Combination2(j, base, top, add, dec, mul, div, equ); 564 } 565 else 566 Combination1(j, base, top, add, dec, mul, div, equ); 567 if (HaveBracket == 1){ 568 AddBrackets(j, add, dec, mul, div, equ, LBra, RBra); 569 } 570 571 } 572 } 573 } 574 return 0; 575 }
运行结果如下:
cmd输出:
1.txt文件输出:
总结:这一次的实验我感觉蛮难的,我差不多花了4个晚上外加一个星期六才写完,而且这也是勉强实现功能,在编写功能模块时,总是单独测试都运行十分OK,但是几个功能一迭加就老是BUG,然后花1-2小时去调试解决,好麻烦,当然在实现真分数插入括号时老是出现错误,我都不知道该怎么办了-_-!! 总之,这次的程序不能说完美吧,但还是勉强能实现功能。
项目计划总结:
日期\任务 | 听课 | 编写程序 | 查阅资料 | 日总计 |
星期一 | 2 | 1 | 1 | 4 |
星期二 | 2 | 2 | ||
星期三 | 2 | 1 | 3 | |
星期四 | 2 | 2 | 4 | |
星期五 | 3 | 1 | 4 | |
星期六 | 5 | 5 | ||
星期日 | ||||
周总计 | 4 | 15 | 3 |
22 |
时间记录日志:
日期 | 开始时间 | 结束时间 | 中断时间 | 静时间 | 活动 | 备注 |
3/7 | 14:00 | 15:50 | 10 | 100 | 听课 | 软件工程 |
19:30 | 21:50 | 10 | 130 | 编写程序 | 编写第二次程序&查资料 | |
3/8 | 19:20 | 21:45 | 10 | 135 | 编写程序 | |
3/9 | 16:30 | 17:40 | 10 | 60 | 查阅资料 | 查资料和同学间交流 |
19:20 | 21:50 | 20 | 130 | 编写程序 | ||
3/10 | 14:00 | 15:50 | 10 | 100 | 听课 | 软件工程 |
19:20 | 21:20 | 120 | 编写程序 | 调试程序寻找错误地方 | ||
3/11 | 18:10 | 21:40 | 20 | 190 | 编写程序 | 调试程序为主 |
7:30 | 9:00 | 10 | 80 | 看书 | 看数据结构书寻找解决办法 | |
3/12 | 8:00 | 15:00 | 50 | 370 | 调试 | 最终调试 |
16:00 | 17:00 | 60 | 博客 | 撰写博客 |
缺陷记录日志:
日期 | 编号 | 引入阶段 | 排除阶段 | 修复时间&问题描述 |
3/7 | 1 | 编码 | 编译 | 1小时,真分数叠加,后来发现是输出时除号和正分数符号弄反了 |
3/8 | ||||
3/9 | ||||
3/10-3/11 | 2 | 编码 | 编译 | 4小时,循环叠加混乱,不是忘记赋值就是忘记跳出循环 |
3/11-3/12 | 3 | 编码 | 编译 | 4小时,括号添加数量不对,后来发现是数组越界 |