改进计算器
Posted hml-xxbj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了改进计算器相关的知识,希望对你有一定的参考价值。
只改了主程序calc.cpp
1 #include <iostream> 2 #include "Comp.h" 3 #include "Isop.h" 4 #include <stack> 5 #include <string> 6 #include <math.h> 7 using namespace std; 8 /** 9 1. 接收用户输入//没有判断是否有非法字符 10 2. 处理 11 3. 输出 12 */ 13 14 15 /** 16 stl中的栈pop()返回空值,top()返回引用(左值,可改)和常引用(做右值,不可改) 17 top的定义: 18 T& top(void); 19 const T& top(void) const; 20 21 为什么pop()没有返回值? 22 为了防止复制失败,栈顶的值也消失 23 T t = s.pop();//pop()如果返回值,取出值(栈中无该值),然后赋值失败,值消失 24 */ 25 26 27 /* 28 要自己写一个类,分别来存放float和char 29 用string的话,float用不了,并且不能双位数 30 */ 31 32 void cleanfz(float * num1,float * num2,char * oper1,stack<float> & fz,stack<float> & num); 33 bool isNum(char c); 34 float calc(float num1,float num2,char c); //做计算的函数 35 int main() 36 { 37 stack<float> num; //数据 38 stack<char> op; //操作符 39 stack<float> fz; //注意类型要转换回去 40 string exp; //保存表达式 41 Comp com; //作比较,决定什么时候计算 42 Isop isop; //判断是否是操作符 43 char oper1; 44 char oper2; 45 float num1; 46 float num2; 47 float result; 48 int flag = 0; 49 50 //1. 51 cout << "welcome to MyCalculator! "; 52 cout << "please input your expression: "; 53 cin>>exp; 54 cin.ignore(); 55 //string 自己的函数,为什么要两次回车 56 //getline(cin,exp); 57 58 59 //2.边入栈边处理 60 for(int i=0;i<exp.length();i++) 61 { 62 if(isop((char)exp[i])) //操作符 63 { 64 if(exp[i]==‘)‘) //如果是反括号, 65 { 66 67 if(!num.empty()) 68 { 69 num1 = (float)num.top(); 70 num.pop(); 71 } 72 else 73 { 74 cout << "please input something!" << endl; 75 exit(1); 76 } 77 if(!op.empty()) 78 { 79 oper1 = op.top(); 80 op.pop(); 81 } 82 else 83 { 84 cout << "please input something!" << endl; 85 exit(1); 86 } 87 while(oper1!=‘(‘) //出栈是(,丢弃,一次计算完成 88 { 89 if(op.empty()) //小括号不成对 90 { 91 cout << "input errorn"; 92 exit(0); 93 } 94 95 if(!op.empty()) 96 { 97 oper2 = op.top(); 98 op.pop(); 99 if(com(oper1,oper2)) 100 { 101 if(!num.empty()){ 102 num2 = (float)num.top(); 103 num.pop(); 104 } 105 else 106 { 107 cout << "no elements1!" << endl; 108 exit(1); 109 } 110 //做计算 111 result = calc(num2,num1,oper1); 112 num.push(result); 113 //1种做法是把辅助栈弹回,2是把辅助栈中的计算出来,实现第二种 114 //cleanfz(&num1,&num2,&oper1,fz,num); 115 while(!fz.empty()) 116 { 117 oper1 = (char)fz.top(); 118 fz.pop(); 119 if(!fz.empty()){ 120 num1 = (float)fz.top(); 121 fz.pop(); 122 } 123 else 124 { 125 cout << "no element2!" <<endl; 126 exit(1); 127 } 128 if(!num.empty()) 129 { 130 num2 = (float)num.top(); 131 num.pop(); 132 } 133 else 134 { 135 cout << "no element3!" << endl; 136 exit(1); 137 } 138 result = calc(num1,num2,oper1); 139 num.push(result); 140 } 141 oper1 = oper2; 142 if(!num.empty()) 143 { 144 num1 = (float)num.top(); 145 num.pop(); 146 } 147 else 148 { 149 cout << "no element3!" << endl; 150 } 151 } 152 else 153 { 154 fz.push(num1); 155 fz.push(oper1); 156 oper1 = oper2; 157 if(!num.empty()) 158 { 159 num1 = (float)num.top(); 160 num.pop(); 161 } 162 else 163 { 164 cout << "no element3!" << endl; 165 exit(1); 166 } 167 } 168 } 169 }//直到取出小括号 170 num.push(num1); 171 } 172 else if(exp[i]==‘]‘) //如果是反大括号 173 { 174 175 } 176 else //以上都不是,就是普通符号,入栈 177 { 178 op.push(exp[i]); 179 } 180 } 181 else if(isNum(exp[i])) //数据入栈 182 { 183 float res = 0; 184 if(isNum(exp[i])) 185 { 186 res = 0; 187 while(isNum(exp[i])) 188 { 189 res = res*10+exp[i]-48; 190 if(exp[i+1]==‘.‘) 191 { 192 i+=2; 193 int count = 0; 194 while(isNum(exp[i])) 195 { 196 count++; 197 res += (exp[i]-48)*pow(0.1,count); 198 i++; 199 } 200 i--;//退回非数字的字符 201 } 202 i++; 203 } 204 i--; //退回 205 } 206 num.push(res); 207 } 208 else ///输入不是操作符不是数字 209 { 210 cout << "input error!" << endl; 211 } 212 } 213 //入栈完毕,做处理,没有括号的情况 214 215 216 if(!num.empty()) 217 { 218 num1 = (float)num.top(); 219 num.pop(); 220 } 221 else 222 { 223 cout << "no element4!" << endl; 224 exit(1); 225 } 226 if(!op.empty()){ 227 oper1 = op.top(); 228 op.pop(); 229 } 230 else 231 { 232 cout << "no element5!" << endl; 233 exit(1); 234 } 235 while(!op.empty()) 236 { 237 oper2 = op.top(); 238 op.pop(); 239 if(com(oper1,oper2)) 240 { 241 if(!num.empty()) 242 { 243 num2 = (float)num.top(); 244 num.pop(); 245 } 246 else 247 { 248 cout << "no elementt6!" << endl; 249 exit(1); 250 } 251 //做计算 252 result = calc(num1,num2,oper1); 253 num.push(result); 254 //1种做法是把辅助栈弹回,2是把辅助栈中的计算出来,实现第二种 255 //处理逻辑与之前一样,可写成函数 256 //判断是否可以取值,栈是否为空,可以写成函数 257 //cleanfz(&num1,&num2,&oper1,fz,num); 258 259 while(!fz.empty()) 260 { 261 oper1 = (char)fz.top(); 262 fz.pop(); 263 if(!fz.empty()) //第一个数 264 { 265 num1 = (float)fz.top(); 266 fz.pop(); 267 } 268 else 269 { 270 cout << "no element7!" << endl; 271 exit(1); 272 } 273 if(!num.empty()) //第二个数 274 { 275 num2 = (float)num.top(); 276 num.pop(); 277 } 278 else 279 { 280 cout << "no element8!" << endl; 281 exit(1); 282 } 283 result = calc(num1,num2,oper1); 284 num.push(result); 285 } 286 } 287 else 288 { 289 fz.push(num1); 290 fz.push(oper1); 291 } 292 293 oper1 = oper2; //回到最初状态 294 if(!num.empty()) 295 { 296 num1 = (float)num.top(); 297 num.pop(); 298 } 299 else 300 { 301 cout << "no element9!" << endl; 302 } 303 } 304 //计算op栈中最后一个元素 305 if(!num.empty()) 306 { 307 num2 = (float)num.top(); 308 num.pop(); 309 } 310 else 311 { 312 cout << "no element10!" << endl; 313 exit(1); 314 } 315 result = calc(num1,num2,oper1); 316 num.push(result); 317 318 //op栈空,但是fz没空的情况 319 //cleanfz(&num1,&num2,&oper1,fz,num); 320 while(!fz.empty()) 321 { 322 oper1 = (char)fz.top(); 323 fz.pop(); 324 if(!fz.empty()) //第一个数 325 { 326 num1 = (float)fz.top(); 327 fz.pop(); 328 } 329 else 330 { 331 cout << "no element7!" << endl; 332 exit(1); 333 } 334 if(!num.empty()) //第二个数 335 { 336 num2 = (float)num.top(); 337 num.pop(); 338 } 339 else 340 { 341 cout << "no element8!" << endl; 342 exit(1); 343 } 344 result = calc(num1,num2,oper1); 345 num.push(result); 346 } 347 348 cout << "the expression equals to "<< result << endl; 349 return 0; 350 } 351 352 353 float calc(float num1,float num2,char c) 354 { 355 float r=0; 356 switch(c) 357 { 358 case ‘+‘: 359 r = num2+num1; 360 break; 361 case ‘-‘: 362 r = num2-num1; 363 break; 364 case ‘*‘: 365 r = num2*num1; 366 break; 367 case ‘/‘: 368 if(num1==0) 369 { 370 cout << "error:divede 0! "; 371 exit(0); 372 } 373 r = num2/num1; 374 break; 375 default: 376 cout << "there are some bugs!" <<endl; 377 378 } 379 return r; 380 } 381 382 383 bool isNum(char c) 384 { 385 c = (int)c; 386 if((47<c)&&(c<58)) 387 { 388 return true; 389 } 390 391 return false; 392 } 393 394 395 void cleanfz(float * num1,float * num2,char * oper1,stack<float> & fz,stack<float> & num) 396 { 397 int result=0; 398 while(!fz.empty()) 399 { 400 *oper1 = (char)fz.top(); 401 fz.pop(); 402 if(!fz.empty()) //第一个数 403 { 404 *num1 = (float)fz.top(); 405 fz.pop(); 406 } 407 else 408 { 409 cout << "no element7!" << endl; 410 exit(1); 411 } 412 if(!num.empty()) //第二个数 413 { 414 *num2 = (float)num.top(); 415 num.pop(); 416 } 417 else 418 { 419 cout << "no element8!" << endl; 420 exit(1); 421 } 422 result = calc(*num1,*num2,*oper1); 423 num.push(result); 424 } 425 }
以上是关于改进计算器的主要内容,如果未能解决你的问题,请参考以下文章
代码在计算最大连续 1 时失败 4/9 案例,我该如何改进?
Vue3官网-高级指南(十七)响应式计算`computed`和侦听`watchEffect`(onTrackonTriggeronInvalidate副作用的刷新时机`watch` pre)(代码片段