结对项目2.0版
Posted 圆润的馒头君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对项目2.0版相关的知识,希望对你有一定的参考价值。
更新内容:
1.在之前基础上实现四个数的四则运算。
2.实现了带有括号的运算。
存在问题:
运算过程中偶尔会有-nan(ind)的结果,还在找原因。
部分代码如下:
1 //运算符栈的长度 2 #define OPSTACK_LENGTH 5 3 //操作数栈的长度 4 #define NUMSTACK_LENGTH 100 5 //输入串的最大长度 6 #define MAX_STRING_LENGTH 100 7 #pragma warning(disable:4996) 8 //表达式结构体 9 struct biaodashi 10 { 11 char word; 12 }; 13 //运算符结构体 14 struct operatorStruct 15 { 16 //运算符名称 17 char name; 18 //优先级 19 int priority; 20 //目数,即操作数个数,例如单目运算符为1,双目运算符2 21 int opnum; 22 }; 23 24 typedef struct operatorStruct OPERATOR; 25 26 //运算符栈 27 OPERATOR opStack[OPSTACK_LENGTH]; 28 //运算符栈顶指针 29 30 //操作数栈 31 double numStack[NUMSTACK_LENGTH]; 32 //操作数栈顶指针 33 int opStackTop = -1; 34 int numStackTop = -1; 35 36 //获取一个字符所代表的运算符的优先级 37 int getPriority(char name) 38 { 39 if (name == \'(\' || name == \')\') 40 { 41 return 0; 42 } 43 if (name == \'!\') 44 { 45 return 3; 46 } 47 if (name == \'*\' || name == \'/\') 48 { 49 return 2; 50 } 51 if (name == \'+\' || name == \'-\') 52 { 53 return 1; 54 } 55 56 } 57 //获取一个字符所代表的运算符的目数 58 int getOpNum(char name) 59 { 60 if (name == \'*\' || name == \'/\' || name == \'+\' || name == \'-\') 61 { 62 return 2; 63 } 64 if (name == \'!\') 65 { 66 return 1; 67 } 68 if (name == \'(\' || name == \')\') 69 { 70 return 0; 71 } 72 73 } 74 75 //运算符压栈 76 void pushOperator(OPERATOR op) 77 { 78 if (opStackTop < OPSTACK_LENGTH - 1) 79 { 80 opStack[++opStackTop] = op; 81 } 82 } 83 //运算符出栈 84 OPERATOR popOperator() 85 { 86 if (opStackTop >= 0) 87 { 88 return opStack[opStackTop--]; 89 } 90 } 91 //操作数压栈 92 void pushNumber(double num) 93 { 94 if (numStackTop < NUMSTACK_LENGTH - 1) 95 { 96 numStack[++numStackTop] = num; 97 } 98 } 99 //操作数出栈 100 double popNumber() 101 { 102 if (numStackTop >= 0) 103 { 104 return numStack[numStackTop--]; 105 } 106 } 107 108 //从操作数栈中弹出两个操作数,完成一次双目运算 109 double opertate2Num(OPERATOR op) 110 { 111 double num2 = popNumber(); 112 double num1 = popNumber(); 113 if (op.name == \'+\') 114 { 115 return num1 + num2; 116 } 117 if (op.name == \'-\') 118 { 119 return num1 - num2; 120 } 121 if (op.name == \'*\') 122 { 123 return num1 * num2; 124 } 125 if (op.name == \'/\') 126 { 127 return num1 / num2; 128 } 129 } 130 //从操作数栈中弹出一个操作数,完成一次单目运算 131 double opertate1Num(OPERATOR op) 132 { 133 double num = popNumber(); 134 if (op.name == \'!\') 135 { 136 double result = 1; 137 while (num > 1) 138 { 139 result *= num; 140 num--; 141 } 142 return result; 143 } 144 145 } 146 //完成一次运算 147 double operate(OPERATOR op) 148 { 149 if (op.opnum == 1) 150 { 151 return opertate1Num(op); 152 } 153 else if (op.opnum == 2) 154 { 155 return opertate2Num(op); 156 } 157 158 } 159 //四则运算计算器 160 double Calculate(struct biaodashi *string) 161 { 162 163 int i; 164 OPERATOR op, topOp;//op为从当前输入串中提取的一个运算符,topOp为运算符栈栈顶的运算符 165 166 topOp.name = \'#\'; 167 topOp.priority = 0; 168 topOp.opnum = 0; 169 pushOperator(topOp);//压入#作为初始运算符 170 171 for (i = 0; string[i].word != \'=\';i++) 172 { 173 //从输入串中取出一个字符作为开始,进行处理,直到表达式结束 174 if (string[i].word!=\'+\' && string[i].word != \'-\'&& string[i].word != \'*\'&& string[i].word != \'/\'&& string[i].word != \'(\'&& string[i].word != \')\') 175 { 176 //如果是操作数,将整个操作数提取出来,压入操作数栈 177 pushNumber((double)(string[i].word)); 178 } 179 else 180 { 181 op.name = string[i].word; 182 op.priority = getPriority(string[i].word); 183 op.opnum = getOpNum(string[i].word); 184 topOp = popOperator(); 185 if (op.name == \'(\') 186 { 187 //如果是\'(\',将从栈顶弹出的运算符压回栈内,并将当前运算符则压栈 188 pushOperator(topOp); 189 pushOperator(op); 190 } 191 else if (op.name == \')\') 192 { 193 //如果是\')\',则进行运算,每次运算结果作为一个操作数压入操作数栈,直到将\'(\'弹出运算符栈 194 while (topOp.name != \'(\') 195 { 196 pushNumber(operate(topOp)); 197 topOp = popOperator(); 198 } 199 } 200 else 201 { 202 //如果是普通运算符 203 if (topOp.name != \'#\' && op.priority <= topOp.priority) 204 { 205 //如果运算符栈非空,且当前运算符的优先级大于栈顶运算符,则进行一次运算,将结果压入操作数栈 206 pushNumber(operate(topOp)); 207 } 208 else 209 { 210 //否则将从栈顶弹出的运算符压回 211 pushOperator(topOp); 212 } 213 //将当前运算符压栈 214 pushOperator(op); 215 } 216 } 217 218 } 219 //完成栈内剩余的运算 220 while ((topOp = popOperator()).name != \'#\') 221 { 222 pushNumber(operate(topOp)); 223 } 224 //操作数栈中剩下的最后一个数即为结果 225 return popNumber(); 226 }
这部分为计算器,主体来自http://blog.csdn.net/bhq2010/article/details/7516369,做了些必要的修改。
1 int N = 0, i = 0; 2 int optr1 = 0, optr2 = 0, optr3 = 0, kuohao = 0; 3 int num1, num2, num3, num4; 4 5 double answer1, answer2; 6 struct biaodashi string[15]; 7 char str[] = "+-*/", ch; 8 9 srand((unsigned)time(0)); 10 11 printf("请输入本次测试的题目数量:"); //手动输入题目数量 12 scanf("%d", &N); 13 ch = getchar(); 14 15 printf("保留两位小数\\n"); //输入结果如果有小数,保留两位小数
部分主函数代码。
1 for (i = 0; i < N; i++) 2 { 3 num1 = rand() % 100 + 1; //生成随机数 4 num2 = rand() % 100 + 1; 5 num3 = rand() % 100 + 1; 6 num4 = rand() % 100 + 1; 7 optr1 = rand() % 4; 8 optr2 = rand() % 4; 9 optr3 = rand() % 4; 10 kuohao = rand() % 8; 11 if (num1 > 40) 12 { 13 printf("题号:%d\\n", i + 1); 14 printf("%d %c %d %c %d %c %d=?\\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4); 15 string[0].word = num1; 16 string[1].word = str[optr1]; 17 string[2].word = num2; 18 string[3].word = str[optr2]; 19 string[4].word = num3; 20 string[5].word = str[optr3]; 21 string[6].word = num4; 22 string[7].word = \'=\'; 23 answer1 = Calculate(string); 24 scanf("%lf", &answer2); 25 ch = getchar(); 26 if ((fabs(answer2-answer1))<0.01) 27 printf("正确\\n"); 28 else printf("错误 正确答案是:%-10.2lf\\n", answer1); 29 }
这部分为不带括号的出题方式,比例大小为60%
else { printf("题号:%d\\n", i + 1); switch (kuohao) { case 1: printf("(%d %c %d) %c %d %c %d=?\\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4); string[0].word = \'(\'; string[1].word = num1; string[2].word = str[optr1]; string[3].word = num2; string[4].word = \')\'; string[5].word = str[optr2]; string[6].word= num3; string[7].word = str[optr3]; string[8].word = num4; string[9].word = \'=\'; break; case 2: printf("(%d %c %d %c %d) %c %d=?\\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4); string[0].word = \'(\'; string[1].word = num1; string[2].word = str[optr1]; string[3].word = num2; string[4].word = str[optr2]; string[5].word = num3; string[6].word = \')\'; string[7].word = str[optr3]; string[8].word = num4; string[9].word = \'=\'; break; case 3: printf("%d %c (%d %c %d) %c %d=?\\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4); string[0].word = num1; string[1].word = str[optr1]; string[2].word = \'(\'; string[3].word = num2; string[4].word = str[optr2]; string[5].word = num3; string[6].word = \')\'; string[7].word = str[optr3]; string[8].word = num4; string[9].word = \'=\'; break; case 4: printf("%d %c (%d %c %d %c %d)=?\\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4); string[0].word = num1; string[1].word = str[optr1]; string[2].word = \'(\'; string[3].word = num2; string[4].word = str[optr2]; string[5].word = num3; string[6].word = str[optr3]; string[7].word = num4; string[8].word = \')\'; string[9].word = \'=\'; break; case 5: printf("%d %c %d %c (%d %c %d)=?\\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4); string[0].word = num1; string[1].word = str[optr1]; string[2].word = num2; string[3].word= str[optr2]; string[4].word = \'(\'; string[5].word = num3; string[6].word = str[optr3]; string[7].word = num4; string[8].word = \')\'; string[9].word = \'=\'; break; case 6: printf(以上是关于结对项目2.0版的主要内容,如果未能解决你的问题,请参考以下文章