1 /* calculate.cpp 2 * 问题描述: 3 * 输入一个只包含个位数字的简单四则运算表达式字符串, 4 * 计算该表达式的值 5 * 注: 6 * 1、表达式只含 +, -, *, / 四则运算符,不含括号 7 * 2、表达式数值只包含个位整数(0-9),且不会出现0作为除数的情况 8 * 3、要考虑加减乘除按通常四则运算规定的计算优先级 9 * 4、除法用整数除法,即仅保留除法运算结果的整数部分。 10 * 比如8/3=2。输入表达式保证无0作为除数情况发生 11 * 5、输入字符串一定是符合题意合法的表达式, 12 * 其中只包括数字字符和四则运算符字符, 13 * 除此之外不含其它任何字符,不会出现计算溢出情况 14 * 要求实现函数:int calculate(int len,char *expStr) 15 * 【输入】 16 * int len: 字符串长度; 17 * char *expStr: 表达式字符串; 18 * 【输出】无 19 * 【返回】 20 * 计算结果 21 * 示例 22 * 1)输入:char *expStr = “1+4*5-8/3” 23 * 函数返回:19 24 * 2)输入:char *expStr = “8/3*3” 25 * 函数返回:6 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <stack> 32 33 //判断运算符的优先级函数 34 int Precede(char a, char b) 35 { 36 switch (a) 37 { 38 case '*': 39 case '/': 40 if ((b == '+') || (b == '-')) 41 { 42 return 1; //a的优先级高于b 43 } 44 else 45 { 46 return 0; //a的优先级等于b 47 } 48 case '+': 49 case '-': 50 if ((b == '*') || (b == '/')) 51 { 52 return -1; //a的优先级低于b 53 } 54 else 55 { 56 return 0; 57 } 58 default: 59 printf("运算符错误! "); 60 break; 61 } 62 } 63 64 int Operate(int j, int k, char operater) 65 { 66 //int temp = 0; 67 switch (operater) 68 { 69 case '+': 70 return k + j; 71 //break; 72 case '-': 73 return k - j; 74 //break; 75 case '*': 76 return k * j; 77 //break; 78 case '/': 79 //temp = k / j; 80 return k / j; 81 //break; 82 default: 83 printf("运算错误! "); 84 break; 85 } 86 } 87 88 int calculate(int len, char *expStr) 89 { 90 //表达式异常处理,注意len <= 0要加括号 91 if ((len <= 0 ) || (expStr == NULL)) 92 { 93 printf("表达式为空! "); 94 } 95 96 int i = 0, j = 0, k = 0; 97 std::stack<int> date; 98 std::stack<char> operate; 99 100 while (i < len) 101 { 102 if ((expStr[i] >= '0') && (expStr[i] <= '9')) 103 { 104 date.push(expStr[i] - '0'); 105 i++; 106 } 107 else if ((expStr[i] == '+') || (expStr[i] == '-') 108 || expStr[i] == '*' || expStr[i] == '/') 109 { 110 if (operate.empty()) 111 { 112 operate.push(expStr[i]); 113 i++; 114 } 115 else 116 { 117 //与栈顶运算符判断优先级 118 switch (Precede(expStr[i], operate.top())) 119 { 120 case 0: 121 case -1: //栈顶运算符优先级高 122 j = date.top(); 123 date.pop(); 124 k = date.top(); 125 date.pop(); 126 //date.push(Operate(j, k , expStr[i])); 127 date.push(Operate(j, k , operate.top())); 128 operate.pop(); 129 //i++; 130 break; 131 //case 0: 132 case 1: //栈运算符顶优先级低 133 operate.push(expStr[i]); 134 i++; 135 break; 136 default: 137 printf("优先级判断错误! "); 138 break; 139 } 140 } 141 } 142 else 143 { 144 printf("表达式无法识别! "); 145 break; 146 } 147 } 148 149 while (!operate.empty()) 150 { 151 j = date.top(); 152 date.pop(); 153 k = date.top(); 154 date.pop(); 155 date.push(Operate(j, k , operate.top())); 156 operate.pop(); 157 } 158 159 return date.top(); 160 } 161 162 int main() 163 { 164 int len = 0; 165 int i= 0, input_flag = 0; 166 167 //为了提高程序的鲁棒性,写了下面一段循环 168 //此处关键是flushall()的使用,如果不使用 169 //由于键盘输入缓存的存在使得程序陷入死循环 170 //关于flush()参见我的下一篇博客 171 while (!input_flag) 172 { 173 printf("请输入表达式的长度:"); 174 input_flag = scanf("%d", &len); 175 if (!input_flag) 176 { 177 printf("输入有误,仅可输入数字! "); 178 //flushall(); 179 } 180 flushall(); 181 } 182 183 char *expStr = (char *)malloc(len * sizeof(char)); 184 input_flag = 0; 185 while (!input_flag) 186 { 187 printf("请输入表达式:"); 188 for (i = 0; i < len; i++) 189 { 190 input_flag = scanf("%c", &expStr[i]); 191 //scanf("%c", &expStr[i]); 192 /*if ((i < len) && (expStr[i] == ' ')) 193 { 194 printf("长度不够,请重新输入:"); 195 i = 0; 196 }*/ 197 if (!input_flag) 198 { 199 printf("表达式输入有误! "); 200 flushall(); 201 break; 202 } 203 } 204 } 205 206 printf("表达式的计算结果为:%d ", calculate(len, expStr)); 207 return 0; 208 } 209 210 //#include <iostream> 211 // 212 //using namespace std; 213 // 214 //int calculate(int len, char *expStr) 215 //{ 216 // //定义操作符栈 217 // struct 218 // { 219 // char opdate[200]; 220 // int top; 221 // }opstack; 222 // 223 // //定义栈操作符 224 // opstack.top = -1; 225 // int i = 0; //遍历字符串的下标 226 // int t = 0; //当前后缀表达式的长度 227 // char ch = expStr[i]; 228 // while (ch != ' ') 229 // { 230 // switch (ch) 231 // { 232 // case '+': 233 // case '-': 234 // while (opstack.top != -1) 235 // { 236 // expStr[t] = opstack.opdate[opstack.top]; 237 // opstack.top--; 238 // t++; 239 // } 240 // opstack.top++; 241 // opstack.opdate[opstack.top] = ch; 242 // break; 243 // case '*': 244 // case '/': 245 // while (opstack.top != -1 && 246 // (opstack.opdate[opstack.top] == '*' || 247 // opstack.opdate[opstack.top] == '/')) 248 // { 249 // expStr[t] = opstack.opdate[opstack.top]; 250 // opstack.top--; 251 // t++; 252 // } 253 // opstack.top++; 254 // opstack.opdate[opstack.top] = ch; 255 // break; 256 // default: 257 // expStr[t] = ch; 258 // t++; 259 // break; 260 // } 261 // i++; 262 // ch = expStr[i]; 263 // } 264 // 265 // while (opstack.top != -1) //将栈中所有剩余的运算符出栈 266 // { 267 // expStr[t] = opstack.opdate[opstack.top]; 268 // opstack.top--; 269 // t++; 270 // } 271 // expStr[t] = ' '; 272 // 273 // struct 274 // { 275 // int numeric[200]; 276 // int top; 277 // }date; 278 // date.top = -1; 279 // i = 0; 280 // ch = expStr[i]; 281 // while (ch != ' ') 282 // { 283 // if (ch >= '0' && ch <= '9') 284 // { 285 // date.top++; 286 // date.numeric[date.top] = ch - '0'; 287 // } 288 // else if ('+' == ch) 289 // { 290 // int tmp = date.numeric[date.top - 1] + 291 // date.numeric[date.top]; 292 // date.top--; 293 // date.numeric[date.top] = tmp; 294 // } 295 // else if ('-' == ch) 296 // { 297 // int tmp = date.numeric[date.top - 1] - 298 // date.numeric[date.top]; 299 // date.top--; 300 // date.numeric[date.top] = tmp; 301 // } 302 // else if ('*' == ch) 303 // { 304 // int tmp = date.numeric[date.top - 1] * 305 // date.numeric[date.top]; 306 // date.top--; 307 // date.numeric[date.top] = tmp; 308 // } 309 // else if ('/' == ch) 310 // { 311 // if (date.numeric[date.top] == 0) 312 // { 313 // printf("cannot be zero of the divide "); 314 // exit(1); 315 // } 316 // int tmp = date.numeric[date.top - 1] / 317 // date.numeric[date.top]; 318 // date.top--; 319 // date.numeric[date.top] = tmp; 320 // } 321 // i++; 322 // ch = expStr[i]; 323 // } 324 // return date.numeric[date.top]; 325 //} 326 // 327 //void main() 328 //{ 329 // char expStr[] = "9/3*5"; 330 // printf("%s ", expStr); 331 // int result = calculate(strlen(expStr), expStr); 332 // printf("%d", result); 333 //} 334