#include #include using namespace std; //想法:构建表达式树,进行计算(从右往左) //当然也可以用两个栈,一个存符号一个存数字(从左往右) //辅助 long long fastpow(long long d, long long u){ //d^u,用快速幂 long long result = 1, base = d, b = u; while(b > 0){ if(b & 1) result *= base; base *= base; b >>= 1; } return result; } int level(char c){ switch(c){ case '+': case '-': { return 1; break; } case '*': case '/': { return 2; break; } case '^': { return 3; break; } default: { return 0; break; } } } int findexp(const string& s, int l, int r) { int pos = -1; int min_level = 114514; int js = 0; for (int i = r; i >= l; i--) { if (s[i] == ')') js--; else if (s[i] == '(') js++; if (js == 0 && level(s[i])) { // 对于右结合的^,使用<而不是<= if ((s[i] == '^' && level(s[i]) < min_level) || (s[i] != '^' && level(s[i]) <= min_level)) { min_level = level(s[i]); pos = i; } } } return pos; } long long toNum(const string& s, int l, int r) { long long tmp = 0; // 跳过空格 while (l <= r && s[l] == ' ') l++; while (l <= r && s[r] == ' ') r--; if (l > r) return 0; // 从左到右处理数字 for (int i = l; i <= r; i++) { if (isdigit(s[i])) { tmp = tmp * 10 + (s[i] - '0'); } else { return 0; // 非法字符 } } return tmp; } /* 带符号的版本 long long toNum(const string& s, int l, int r){ long long tmp = 0; bool neg = false; if (s[l] == '-') { neg = true; l++; } for(int i = l; i <= r; i++){ if(isdigit(s[i])) tmp = tmp * 10 + (s[i] - '0'); } return neg ? -tmp : tmp; } */ struct Node{ char sign; long long num; Node* left; Node* right; Node(): sign('?'), num(-1), left(nullptr), right(nullptr) {} Node(char s): sign(s), num(-1), left(nullptr), right(nullptr) {} Node(long long n): sign('?'), num(n), left(nullptr), right(nullptr) {} }; class Expression{ public: string exp; Node* root; long long result; bool isValid; Expression(const string& s): exp(s), root(nullptr), result(-1), isValid(true) {} void inorder(Node* r){ if(!r) return; inorder(r->left); if (r->sign == '?') cout << r->num; else cout << r->sign; inorder(r->right); } Node* build(const string& s, int l, int r){ //[l, r] //处理空格 while(l <= r && s[l] == ' ') l++; while(l <= r && s[r] == ' ') r--; if(l > r) return nullptr; //处理外部括号 if(s[l] == '(' && s[r] == ')'){ bool hasQuote = true; int js = 0; for(int i = l; i <= r; i++){ if(s[i] == '(') js++; else if(s[i] == ')') js--; if(js == 0 && i != r){ hasQuote = false; break; } } if (hasQuote) return build(s, l + 1, r - 1); } int pos = findexp(s, l, r); //处理纯数字 if(pos == -1) { long long x = toNum(s, l, r); //cout << "*" << r << endl; ?为什么输出0 return new Node(x); //无下方节点 } Node* tmp = new Node(s[pos]); tmp->left = build(s, l, pos - 1); tmp->right = build(s, pos + 1, r); return tmp; } long long calc(Node* r, bool& isValid){ if(!r) return 0; //数字 if(r->sign == '?') return r->num; //符号 long long left = calc(r->left, isValid); long long right = calc(r->right, isValid); if(r->num == -1){ char c = r->sign; switch(c){ case '+': return left + right; case '-': return left - right; case '*': return left * right; case '/': { if(right == 0) { isValid = false; return 0; } else return left / right; } case '^': { if(left == 0 && right == 0) { isValid = false; return 0; } return fastpow(left, right); break; } default: return 0; } } } void print(){ inorder(root); } }; int main(){ /* string s; getline(cin, s); Expression tree(s); tree.root = tree.build(s, 0, s.length() - 1); //tree.print(); cout << tree.calc(tree.root, tree.isValid) << endl; //if(!tree.isValid && result != -1) cout << result <