- 题目描述:
-
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
- 输入:
-
测试输入包含若干测试用例,每个测试用例占一行,每行不超过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 }