更新内容:
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(); }
部分主函数代码。
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 }
输出结果:
结果:可以看到第6题出现了-nan(ind)的问题,百度一下意思是not a number,应该是计算过程中出了问题,但是还没找到。