要求1 参考《构建之法》第4章两人合作,结对编程上述功能,要求每人发布随笔1篇 (代码是共同完成的,随笔有以下两种方式:(①允许两人写一份,得一份分数,二人均分;②如果每人写一份,内容不得抄袭,体会需要是自己的,分别得到自己博客的分数)。 (10分)
(1) 给出每个功能的重点、难点、编程收获。
- 功能1:四则运算
重点及难点:随机出题
编程收获:我们是把所有的功能点看完之后,整体编程的
- 功能2:支持括号
重点及难点:
(1)括号的生成
题意共有4个操作数,括号只能出现1个或两个,完全可以列举出所有出现的情况。但是为了迎接挑战,我们采取了自动生成括号的方式。
1.分析可知:括号分为左右两种情况,右括号始终在操作数之后,左括号始终在操作数之前,4个操作数最多可以有3对括号
2.当生成一个操作数后,紧接着的可能是操作符或者右括号
3.可以分两组生成,一组操作数或者“(”;一组操作符或者”)“
4.当左括号小于2生成操作数或”(“,否则只生成操作数;当右括号少于左括号生成操作符和右括号,否则生成操作符
1 /* 2 * 生成方程 3 * pequa:存储方程的结构体 4 */ 5 void rand_equa(pEqua pequa) 6 { 7 int left = 0; //记录左括号 8 int right = 0; //记录右括号 9 int index = 0; //记录方程当前存储的位置 10 bool bol = true; //true生成数字,false生成操作符 11 //srand((unsigned)time(NULL)); 12 for (int i = 0; i < EQUATION_LENGTH;) //每生成一次数字,生成一次操作符 13 { 14 if (bol) 15 { 16 //生成数字或“(” 17 if (left < 2) //左括号小于2生成数字或括号,否则只生成数字 18 { 19 LARGE_INTEGER seed; //设置随机种子,毫秒级 20 QueryPerformanceFrequency(&seed); 21 QueryPerformanceCounter(&seed); 22 srand(seed.QuadPart); 23 24 int rad = rand() % 4; 25 if (rad == 2 && bol) 26 { 27 strcpy_s(pequa->equa[index++], DATA_SIZE, "("); 28 left++; 29 bol = true; 30 continue; 31 } 32 else 33 { 34 strcpy_s(pequa->equa[index++], DATA_SIZE, rand_numb()); 35 i++; 36 bol = false; 37 continue; 38 } 39 } 40 else 41 { 42 //pequa->equa[index++] = rand_numb(false); 43 //char* pChr = rand_numb(false); 44 strcpy_s(pequa->equa[index++], DATA_SIZE, rand_numb()); 45 i++; 46 bol = false; 47 continue; 48 } 49 } 50 else 51 { 52 //生成操作符 53 if (left > right) //右括号少于左括号生成操作符和右括号,否则生成操作符 54 { 55 LARGE_INTEGER seed; 56 QueryPerformanceFrequency(&seed); 57 QueryPerformanceCounter(&seed); 58 srand(seed.QuadPart); 59 if ((rand() % 3) == 2 && bol) 60 { 61 strcpy_s(pequa->equa[index++], DATA_SIZE, ")"); 62 right++; 63 bol = false; 64 } 65 else 66 { 67 LARGE_INTEGER seed; 68 QueryPerformanceFrequency(&seed); 69 QueryPerformanceCounter(&seed); 70 srand(seed.QuadPart); 71 int number = rand() % 4; 72 if (number == 0) 73 { 74 strcpy_s(pequa->equa[index++], DATA_SIZE, "+"); 75 } 76 else if (number == 1) 77 { 78 strcpy_s(pequa->equa[index++], DATA_SIZE, "-"); 79 } 80 else if (number == 2) 81 { 82 strcpy_s(pequa->equa[index++], DATA_SIZE, "*"); 83 } 84 else 85 { 86 strcpy_s(pequa->equa[index++], DATA_SIZE, "/"); 87 } 88 bol = true; 89 } 90 } 91 else 92 { 93 LARGE_INTEGER seed; 94 QueryPerformanceFrequency(&seed); 95 QueryPerformanceCounter(&seed); 96 srand(seed.QuadPart); 97 int number = rand() % 4; 98 if (number == 0) 99 { 100 strcpy_s(pequa->equa[index++], DATA_SIZE, "+"); 101 } 102 else if (number == 1) 103 { 104 strcpy_s(pequa->equa[index++], DATA_SIZE, "-"); 105 } 106 else if (number == 2) 107 { 108 strcpy_s(pequa->equa[index++], DATA_SIZE, "*"); 109 } 110 else 111 { 112 strcpy_s(pequa->equa[index++], DATA_SIZE, "/"); 113 } 114 bol = true; 115 } 116 } 117 } 118 while (right < left) 119 { 120 //char pChr[] = ")"; 121 //pequa->equa[index++] = pChr; 122 strcpy_s(pequa->equa[index++], DATA_SIZE, ")"); 123 right++; 124 } 125 }
(2)运算优先级
设定操作数、”+“或者”-“、”*“或”/“、”(“、”)“的优先级分别为0,1,2,3,4
1.标记待入栈的优先级
2.如果是数字和左括号入栈;如果是右括号,先计算括号内的值,再出栈左括号;如果为 + - ,计算后三个值再入栈,符号入栈;如果为 * / ,并且前一位运算符存在且前一位运算符为 * /,就进行运算。
1 /* 2 * 计算方程结果 3 * equa:方程式 4 * 返回char* 5 */ 6 char* calculate_equa(pEqua equa) 7 { 8 calculate calc; //定义计算式子的栈 9 for (int i = 0; i < DATA_SIZE; i++) 10 { 11 //char* chr = equa->equa[i]; //取一个符号 12 if (strlen(equa->equa[i]) > 10 || strlen(equa->equa[i]) < 1 || equa->equa[i] == "" || equa->equa[i] == "