标准算法
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
class PBTNode {
public:
PBTNode* l;
PBTNode* r;
char op;
LL num;
PBTNode() {
l = NULL;
r = NULL;
}
};
class PrefixBinaryTree {
private:
PBTNode* root;
vector<PBTNode*> token_list;
stack<PBTNode*> st;
vector<PBTNode*> ve;
int pre_map[256];
int pre(char c) {
return pre_map[c];
}
LL string_to_num(string s) {
stringstream ss(s);
LL v;
ss >> v;
return v;
}
LL calc_dfs(PBTNode* p) {
if(p->op == 'x') return p->num;
LL a = calc_dfs(p->l);
LL b = calc_dfs(p->r);
if(p->op == '+') return a + b;
if(p->op == '-') return a - b;
if(p->op == '*') return a * b;
if(p->op == '/') return a / b;
return 0;
}
public:
PrefixBinaryTree() {
memset(pre_map, 0, sizeof(pre_map));
pre_map['+'] = 1;
pre_map['-'] = 1;
pre_map['*'] = 2;
pre_map['/'] = 2;
}
void to_token(string expr) {
string str_t;
int n = expr.length();
int i = 0;
while(i < n) {
char x = expr[i];
if(x == ' ') {
i++;
} else if(pre_map[x] > 0 || x == '(' || x == ')') {
PBTNode* p = new PBTNode;
p->op = x;
token_list.push_back(p);
i++;
} else if(isdigit(x)) {
string str_t;
char y = expr[i];
while(isdigit(y)) {
str_t.push_back(y);
i++;
y = expr[i];
}
PBTNode* p = new PBTNode;
p->op = 'x';
p->num = string_to_num(str_t);
token_list.push_back(p);
}
}
}
void print_token_list() {
for(auto p : token_list) {
if(p->op == 'x') {
printf("[%lld]", p->num);
} else {
printf("[%c]", p->op);
}
}
printf("\n");
}
void to_postfix() {
for(auto p : token_list) {
if(p->op == 'x') {
ve.push_back(p);
} else if(st.empty() || p->op == '(') {
st.push(p);
} else if(p->op == ')') {
while(st.top()->op != '(') {
ve.push_back(st.top());
st.pop();
}
st.pop();
} else {
while(!st.empty() && pre(p->op) <= pre(st.top()->op)) {
ve.push_back(st.top());
st.pop();
}
st.push(p);
}
}
while(!st.empty()) {
ve.push_back(st.top());
st.pop();
}
}
string get_postfix() {
string buf;
stringstream ss;
for(auto p : ve) {
if(p->op == 'x') {
ss << "[" << p->num << "]";
} else {
ss << "[" << p->op << "]";
}
}
ss >> buf;
return buf;
}
void build_tree() {
stack<PBTNode*> sts;
for(auto p : ve) {
if(p->op == 'x') {
p->l = NULL;
p->r = NULL;
sts.push(p);
} else if(pre_map[p->op] > 0) {
p->r = sts.top();
sts.pop();
p->l = sts.top();
sts.pop();
sts.push(p);
}
}
root = sts.top();
}
void preorder(PBTNode* p) {
if(p == NULL) return;
if(p->op == 'x') {
cout << "[" << p->num << "]";
} else {
cout << "[" << p->op << "]";
}
preorder(p->l);
preorder(p->r);
}
void print_preorder() {
printf("preorder:");
preorder(root);
printf("\n");
}
int calc() {
return calc_dfs(root);
}
};
int main() {
PrefixBinaryTree x;
string expr = "2*(36+5)+17/1-4";
x.to_token(expr);
x.to_postfix();
x.build_tree();
LL v = x.calc();
x.print_token_list();
string expr_postfix = x.get_postfix();
cout << expr_postfix << endl;
x.print_preorder();
cout << v << endl;
return 0;
}