77 lines
1.6 KiB
C++
77 lines
1.6 KiB
C++
|
#include <cmath>
|
||
|
#include <iostream>
|
||
|
#include <stack>
|
||
|
#include <unordered_map>
|
||
|
using namespace std;
|
||
|
|
||
|
unordered_map<char, int> priority{{'(', 0}, {')', 0}, {'+', 1}, {'-', 1},
|
||
|
{'*', 2}, {'/', 2}, {'^', 3}};
|
||
|
|
||
|
string in_order2post_order(string src) {
|
||
|
stack<char> in;
|
||
|
string builder;
|
||
|
for (int i = 0; i < src.size(); i++) {
|
||
|
if (src[i] == ' ')
|
||
|
continue;
|
||
|
if (isdigit(src[i]))
|
||
|
builder += src[i];
|
||
|
else {
|
||
|
builder += ' ';
|
||
|
while (!in.empty() && priority[in.top()] >= priority[src[i]]) {
|
||
|
builder += in.top();
|
||
|
in.pop();
|
||
|
}
|
||
|
in.push(src[i]);
|
||
|
}
|
||
|
}
|
||
|
if (builder[builder.size() - 1] != ' ')
|
||
|
builder += ' ';
|
||
|
while (!in.empty()) {
|
||
|
builder += in.top();
|
||
|
in.pop();
|
||
|
}
|
||
|
return builder;
|
||
|
}
|
||
|
|
||
|
int eval(string src) {
|
||
|
stack<int> in;
|
||
|
int num_builder = 0;
|
||
|
for (int i = 0; i < src.size(); i++) {
|
||
|
if (isdigit(src[i])) {
|
||
|
num_builder = num_builder * 10 + src[i] - '0';
|
||
|
} else if (src[i] == ' ') {
|
||
|
in.push(num_builder);
|
||
|
num_builder = 0;
|
||
|
} else {
|
||
|
int y = in.top();
|
||
|
in.pop();
|
||
|
int x = in.top();
|
||
|
in.pop();
|
||
|
switch (src[i]) {
|
||
|
case '+':
|
||
|
in.push(x + y);
|
||
|
break;
|
||
|
case '-':
|
||
|
in.push(x - y);
|
||
|
break;
|
||
|
case '*':
|
||
|
in.push(x * y);
|
||
|
break;
|
||
|
case '/':
|
||
|
in.push(x / y);
|
||
|
break;
|
||
|
case '^':
|
||
|
in.push(pow(x, y));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return in.top();
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
string str;
|
||
|
getline(cin, str);
|
||
|
cout << eval(in_order2post_order(str)) << endl;
|
||
|
}
|