九度oj 题目1019:简单计算器

题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
样例输出:
3.00
13.36

这道题采用两个栈,一个存储符号,一个存储数字
比较运算符的优先级以确定计算的顺序
一开始准备采用巧妙的办法来读取数字,代码如下
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <string>
  5 #include <stack>
  6 #define MAX 202
  7 using namespace std;
  8 
  9 int cmp(char a, char b) {
 10     if(b == '+' || b == '-') {
 11         if(a == '+' || a == '-') {
 12             return 0;
 13         }
 14         else if(a == '*' || a == '/') {
 15             return -1;
 16         }
 17         if(a == '$') {
 18             return -2;
 19         }
 20     }
 21     else if(b == '*' || b == '/') {
 22         return 1;
 23     }
 24 }
 25 
 26 double cal(double a, double b, char c) {
 27     if(c == '+') {
 28         return a + b;
 29     }
 30     else if(c == '-') {
 31         return  a - b;
 32     }
 33     else if(c == '*') {
 34         return a * b;
 35     }
 36     else if(c == '/') {
 37         return a / b;
 38     }
 39 }
 40 stack<double> num;
 41 stack<char> sign;
 42 char temp[MAX];
 43 char calTemp[MAX];
 44 
 45 int main(int argc, char const *argv[])
 46 {
 47     gets(temp);
 48     int numTemp;
 49     int signTemp;
 50     sign.push('$');
 51     
 52     while(strcmp(temp,"0") != 0) {
 53         double ans = 0;
 54         int ptr = 0;
 55         int tlen = strlen(temp);
 56         char signTemp;
 57         int flag = 0;
 58         while(ptr < tlen){
 59             sscanf(&temp[ptr],"%s",calTemp);
 60             if(temp[ptr] >= '0' && temp[ptr] <= '9') {
 61                 sscanf(&temp[ptr],"%d",&numTemp);
 62                 if(flag == 0) {
 63                     num.push(numTemp);
 64                 }
 65                 else if(flag == 1) {
 66                     num.push(numTemp);
 67                     double a = num.top();
 68                     num.pop();
 69                     double b = num.top();
 70                     num.pop();
 71                     char calSign = sign.top();
 72                     sign.pop();
 73                     ans = cal(b, a, calSign);
 74                     num.push(ans);
 75                     flag = 0;
 76                 }
 77                 else if(flag == 2) {
 78                     double a = num.top();
 79                     num.pop();
 80                     double b = num.top();
 81                     num.pop();
 82                     char calSign1 = sign.top();
 83                     sign.pop();
 84                     char calSign2 = sign.top();
 85                     sign.pop();
 86                     ans = cal(b, a, calSign2);
 87                     num.push(ans);
 88                     sign.push(calSign1);
 89                     num.push(numTemp);
 90                     flag = 0;
 91                 }
 92             }
 93             else {
 94                 if(sign.size() == 1 && cmp(sign.top(),calTemp[0]) == -2) {
 95                     sign.push(calTemp[0]);
 96                 }
 97                 else if(cmp(sign.top(),calTemp[0]) == 1){
 98                     sign.push(calTemp[0]);
 99                     flag = 1;
100                 }
101                 else if(cmp(sign.top(),calTemp[0]) == 0){
102                     sign.push(calTemp[0]);
103                     flag = 2;
104                 }
105                 
106             }
107             int clen = strlen(calTemp);
108             ptr = ptr + clen + 1;
109         }
110         while(num.size() >= 1) {
111             double a = num.top();
112             num.pop();
113             double b;
114             if(num.size() != 0) {
115                 b = num.top();
116                 num.pop();
117             }
118             else {
119                 b = 0;    
120             }
121             char calSign = sign.top();
122             sign.pop();
123             ans = cal(b, a, calSign);
124             num.push(ans);
125             if(num.size() == 1) {
126                 break;
127             }
128         }
129         while(num.size() != 0) {
130             num.pop();
131         }
132         printf("%.2lf
", ans);
133 
134         gets(temp);
135     }
136 
137     return 0;
138 }

但提交后run time error ,不明白是哪里出错了

后来修改为如下代码

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <string>
  5 #include <stack>
  6 #define MAX 202
  7 
  8 int cmp(char aq, char bq) {
  9     if(bq == '+' || bq == '-') {
 10         if(aq == '$') {
 11             return 0;
 12         }
 13         return -1;
 14     }
 15     else if(bq == '*' || bq == '/') {
 16         if(aq == '*' || aq == '/') {
 17             return -1;
 18         }
 19         if(aq == '$') {
 20             return 0;
 21         }
 22         return 1;
 23     }
 24 }
 25 
 26 double cal(double a, double b, char c) {
 27     if(c == '+') {
 28         return a + b;
 29     }
 30     else if(c == '-') {
 31         return  a - b;
 32     }
 33     else if(c == '*') {
 34         return a * b;
 35     }
 36     else if(c == '/') {
 37         return a / b;
 38     }
 39 }
 40 std::stack<double> num;
 41 std::stack<char> sign;
 42 char temp[MAX];
 43 char calTemp[MAX];
 44 
 45 int main(int argc, char const *argv[])
 46 {
 47     gets(temp);
 48     double numTemp;
 49     int signTemp;
 50     sign.push('$');
 51     while(strcmp(temp,"0") != 0) {
 52         int numTemp = 0;
 53         int flag = 0;
 54         bool isNum = false;
 55         
 56         int i = 0;
 57         while(i < strlen(temp)) {
 58             while(temp[i] >= '0' && temp[i] <= '9') {
 59                 numTemp = numTemp * 10 + temp[i] - '0';
 60                 i++;
 61                 isNum = true;
 62             }
 63             
 64             if(isNum == true) {
 65                 if(flag == 0) {
 66                     num.push(numTemp);
 67                 }
 68                 else if(flag == 1) {
 69                     double a = num.top();
 70                     num.pop();
 71                     char calSign = sign.top();
 72                     sign.pop();
 73                     double ans = cal(a, numTemp, calSign);
 74                     num.push(ans);
 75                     flag = 0;
 76                 }
 77                 else if(flag == -1) {
 78                     double a = num.top();
 79                     num.pop();
 80                     double b = num.top();
 81                     num.pop();
 82                     char calSign1 = sign.top();
 83                     sign.pop();
 84                     char calSign2 = sign.top();
 85                     sign.pop();
 86                     double ans = cal(b, a, calSign2);
 87                     num.push(ans);
 88                     sign.push(calSign1);
 89                     num.push(numTemp);
 90                     flag = 0;
 91                 }
 92                 numTemp = 0;
 93                 isNum = false;
 94             }
 95             else if(temp[i] != ' '){
 96                 flag = cmp(sign.top(),temp[i]);
 97                 sign.push(temp[i]);
 98                 isNum = false;
 99             }
100             i++;
101         }
102         double a = num.top();
103         num.pop();
104         double b = num.top();
105         num.pop();
106         char calSign = sign.top();
107         sign.pop();
108         double res = cal(b, a, calSign);
109         
110         printf("%.2lf
", res);
111         gets(temp);
112     }
113 
114     return 0;
115 }

一开始把 '==' 打成了 '=',结果出现了匪夷所思的错误,经过多次排查,终于发现错误。以后要注意!!!!!!!!!!!!

-----9-17更新

事实上,如果只有加减乘除的话,还可以采用下面的办法,用一个数组去存储加减的数,遇到乘除法先算出来再存到数组中,最后直接算这个数组中数的和,代码如下

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 char str[220];
 5 double dealed[220];
 6 
 7 int main(int argc, char const *argv[])
 8 {
 9     while(gets(str) != 0 && strcmp(str,"0") != 0) {
10         int len = strlen(str);
11         int isP = 1;
12         int i = 0;
13         int p = 0;
14         int isM = 0;//0 null ,1 * ,2 /
15         double last = 0;
16         while(i < len) {
17             double tmp = 0;
18             while(i < len && str[i] >= '0' && str[i] <= '9') {
19                 tmp = 10*tmp + str[i] - '0';
20                 i++;
21             }
22             while(i < len && str[i] == ' ') {
23                 i++;
24             }
25             if(isM == 1) {
26                 tmp = tmp * last;
27                 isM = 0;
28             }
29             else if(isM == 2) {
30                 tmp = last /tmp;
31                 isM = 0;
32             }
33             if(i < len) {
34                 if(str[i] == '+') {
35                     dealed[p++] = tmp * isP;
36                     isP = 1;
37                 }
38                 else if(str[i] == '-') {
39                     dealed[p++] = tmp * isP;
40                     isP = -1;
41                 }
42                 else if(str[i] == '*') {
43                     last = tmp;
44                     isM = 1;
45                 }
46                 else if(str[i] == '/') {
47                     last = tmp;
48                     isM = 2;
49                 }
50                 i++;
51                 while(i < len && str[i] == ' ') {
52                     i++;
53                 }
54             }
55             else {
56                 dealed[p++] = tmp * isP;
57             }
58             
59         }
60         double ans = 0;
61         for(int i = 0; i < p; i++) {
62             ans = ans + dealed[i];
63         }
64         printf("%.2lf
",ans);
65     }    
66     return 0;
67 }
原文地址:https://www.cnblogs.com/jasonJie/p/5680231.html