18.12.21 DSA 中缀表达式的值
描述
人们熟悉的四则运算表达式称为中缀表达式,例如(23+34*45/(5+6+7))。在程序设计语言中,可以利用堆栈的方法把中缀表达式转换成保值的后缀表达式(又称逆波兰表示法),并最终变为计算机可以直接执行的指令,得到表达式的值。
给定一个中缀表达式,编写程序,利用堆栈的方法,计算表达式的值。输入第一行为测试数据的组数N
接下来的N行,每行是一个中缀表达式。表达式中只含数字、四则运算符和圆括号,操作数都是正整数,数和运算符、括号之间没有空格。中缀表达式的字符串长度不超过600。
输出
对每一组测试数据输出一行,为表达式的值
样例输入
3
3+5*8
(3+5)*8
(23+34*45/(5+6+7))
样例输出
43
64
108
提示
注意:运算过程均为整数运算(除法运算'/'即按照C++定义的int除以int的结果,测试数据不会出现除数为0的情况),输出结果也为整数(可能为负)。
中间计算结果可能为负。
1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 #include <stack> 5 #include <string> 6 #include <math.h> 7 #include <queue> 8 #include <stdio.h> 9 #include <string.h> 10 #include <set> 11 #include <vector> 12 #define maxn 2005 13 #define inf 999999 14 #define cha 127 15 #define eps 1e-6 16 #define oo 1503 17 using namespace std; 18 19 int n; 20 char line[700]; 21 stack<char>sig; 22 queue<string>q; 23 24 void toaft() { 25 for (int i = 0; line[i]; i++) { 26 if (line[i] <= '9'&&line[i] >= '0') { 27 string t; 28 while (line[i] <= '9'&&line[i] >= '0') 29 t.push_back(line[i++]); 30 i--; 31 q.push(t); 32 } 33 else if (line[i] == '(') 34 sig.push('('); 35 else if (line[i] == ')') { 36 while (1) 37 { 38 char sigtmp = sig.top(); 39 sig.pop(); 40 if (sigtmp == '(') 41 break; 42 q.push(string(1,sigtmp)); 43 } 44 } 45 else if (sig.empty()) 46 sig.push(line[i]); 47 else if (line[i] == '+' || line[i] == '-') { 48 while (!sig.empty()) 49 { 50 char ch = sig.top(); 51 if (ch == '(') 52 break; 53 sig.pop(); 54 q.push(string(1,ch)); 55 } 56 sig.push(line[i]); 57 } 58 else if (line[i] == '*' || line[i] == '/') { 59 while (!sig.empty()) 60 { 61 char ch = sig.top(); 62 if (ch == '(' || ch == '+' || ch == '-') 63 break; 64 sig.pop(); 65 q.push(string(1, ch)); 66 } 67 sig.push(line[i]); 68 } 69 } 70 while (!sig.empty()) { 71 char ch = sig.top(); sig.pop(); 72 q.push(string(1,ch)); 73 } 74 } 75 76 void calculate() { 77 stack<int>all; 78 while(!q.empty()) { 79 string t = q.front(); 80 if (t[0] <= '9'&&t[0] >= '0') 81 all.push(atoi(t.c_str())); 82 else { 83 int arg1 = all.top(); all.pop(); 84 int arg2 = all.top(); all.pop(); 85 int tmp; 86 if (t[0] == '+') 87 tmp = arg1 + arg2; 88 else if (t[0] == '-') 89 tmp = arg2 - arg1; 90 else if (t[0] == '*') 91 tmp = arg1 * arg2; 92 else if (t[0] == '/') 93 tmp = arg2 / arg1; 94 all.push(tmp); 95 } 96 q.pop(); 97 } 98 int ans = all.top(); all.pop(); 99 printf("%d\n", ans); 100 } 101 102 void init() { 103 scanf("%d", &n); 104 while (n--) { 105 cin >> line; 106 while(!sig.empty())sig.pop(); 107 toaft(); 108 calculate(); 109 } 110 } 111 112 int main() { 113 init(); 114 return 0; 115 }
用字符串存后缀表达式死活过不了
此题竟成为本学期WA的时间最长的题
注定失败的战争,也要拼尽全力去打赢它;
就算输,也要输得足够漂亮。