简单计算器
Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2
4 + 2 * 5 - 7 / 11 0
Sample Output
3.00 13.36
————————————————————————————————————————————————————分割线
简单分析:
栈的基本应用,模拟计算机的底层计算功能。非负整数表示0也可出现在表达式中,小数点后两位表示需要用double类型来存储数据。
这类问题转化为后缀表达式来做,更常规正式点,编写速度更快;不过,我还是用基本两个栈的模拟,先大致理清几类思路,然后尝试编程,才测试各种自造地合理的尽可能全面的样例:哪里有bug就去补哪里。(如果思路没有理清,比较费时间吧!简单题貌似还好说!)
代码里的注释给的比较详细,自己点开看看。给出下面几组参考数组,只要可以正确基本可以AC:
1 + 2
1 + 2 * 3 - 4 / 5
1111+220/220*1+1*1*0
2*2*2/8-4+5/5/5*5
16*8/4+7-3/3*9
0-8+9
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<stack> 7 using namespace std; 8 #define N 60010 9 stack<double>num; double arr1[211]; //存储数字的栈,arr1[]存贮分离出来的数字 10 stack<char>op;double arr2[211]; //存贮运算符的栈 ,arr2存贮分离出来的运算符 11 12 int pos1,pos2; //pos1和POS2分别表示arr1和arr2的长度 13 char str[300]; //输入数据时的原字符串 14 15 void fact1() //將字符串中的數字和运算符提取出来存放进数组里 16 { 17 int i=0; 18 int len=strlen(str); 19 pos1=pos2=0; 20 while(i<len) 21 { 22 while(i<len&&str[i]==‘ ‘)i++; //处理空格 23 if(i==len)break; 24 if(str[i]>=‘0‘&&str[i]<=‘9‘) //分离数字(比如1234,1后面肯定是数字,4后面不是数字) 25 { 26 double sum=0.0; 27 for(; i<len&&str[i]>=‘0‘&&str[i]<=‘9‘; i++) 28 sum=sum*10.0+str[i]-‘0‘; 29 arr1[pos1++] = 1.0*sum; 30 } 31 else //分离字符 32 { 33 arr2[pos2++]=str[i++]; 34 } 35 } 36 } 37 void solve() 38 { 39 fact1(); //处理字符串 40 char nowop; 41 int p1=0; //指向arr1的要使用时的数字下标,初始时为0表示最早从arr1【0】开始 42 int p2=0; //指向arr2的要使用时的字符的下标, 43 num.push(arr1[p1++]); 44 op.push(arr2[p2++]); 45 while(p1<pos1||p2<pos2||num.size()>=2) //判断循环条件 46 { 47 while(num.size()<2&&p1<pos1) //维持数字栈中保留两个 48 num.push(arr1[p1++]); 49 if(p2<pos2&&op.empty()) //维持运算符栈中保留1个运算符 50 op.push(arr2[p2++]); 51 52 if(op.top()==‘*‘||op.top()==‘/‘) //直接可以进行运算,如3*7/8+4 时,3*7可直接算 53 { 54 double n1,n2; 55 n1=num.top();num.pop(); 56 n2=num.top();num.pop(); 57 nowop=op.top();op.pop(); 58 if(nowop==‘*‘) 59 num.push(n2*n1); 60 else 61 num.push(n2/n1); 62 } 63 //栈外的运算符级别高,例如3+5*8时,‘’*‘’级别大于‘’+‘’ 64 else if(p2<pos2&&(nowop=arr2[p2])&&(nowop==‘*‘||nowop==‘/‘)&&(op.top()==‘+‘||op.top()==‘-‘)) 65 { 66 double s1; 67 if(nowop==‘*‘) 68 s1=num.top()*arr1[p1++]; 69 else 70 s1=num.top()/arr1[p1++]; 71 num.pop(); 72 num.push(s1); 73 p2++; //运算符数组指向下一位 74 } 75 else //栈外的运算符等级与栈内相等,或者无运算符,例如5+9-6,’-‘号相对’+‘平级 76 { 77 double n1,n2; 78 n1=num.top();num.pop(); 79 n2=num.top();num.pop(); 80 nowop=op.top();op.pop(); 81 if(nowop==‘-‘) 82 num.push(n2-n1); 83 else 84 num.push(n1+n2); 85 } 86 } 87 printf("%.2lf\n",num.top()); 88 } 89 int main() 90 { 91 while(gets(str),str[0]!=‘0‘||strlen(str)!=1) 92 //谨防样例:0+0(也就说以0开头的式子也合法,这时需要再判一下长度!) 93 { 94 while(!num.empty()) 95 num.pop(); 96 while(!op.empty()) 97 op.pop(); 98 solve(); 99 } 100 return 0; 101 }