
链接:
题解:
1.按照优先级构造表达式树,true/false(INT_MAX) > and(2) > or(1)d
2.然后后序and or求值,可以做短路求值
cpp
#include <string>
#include <vector>
#include <stack>
#include <sstream>
#include <climits>
using namespace std;
class ExpTreeNode {
public:
string symbol;
ExpTreeNode *left, *right;
int priority; // 用于构建表达式树时的优先级比较
ExpTreeNode(string symbol) {
this->symbol = symbol;
this->left = this->right = nullptr;
this->priority = 0; // 默认值
}
};
class Solution {
public:
/**
* @param expression: a string that representing an expression
* @return: the result of the expression
*/
string evaluation(string &expression) {
// 1. 分词
vector<string> tokens;
stringstream ss(expression);
string token;
while (ss >> token) {
tokens.push_back(token);
}
if (tokens.empty()) return "error";
// 2. 语法检查(仅检查 token 合法性及顺序,不构建树)
bool expectOperand = true; // 当前是否期望操作数
for (const string &t : tokens) {
if (t == "true" || t == "false") {
if (!expectOperand) return "error";
expectOperand = false;
} else if (t == "and" || t == "or") {
if (expectOperand) return "error";
expectOperand = true;
} else {
return "error"; // 非法 token
}
}
if (expectOperand) return "error"; // 以运算符结尾
// 3. 构建表达式树
ExpTreeNode* root = build(tokens);
if (!root) return "error";
// 4. 后序遍历计算布尔值
bool result = evaluateTree(root);
// 5. 释放内存
releaseTree(root);
return result ? "true" : "false";
}
private:
// 返回运算符优先级,操作数优先级最高
int getPriority(const string &op) {
if (op == "or") return 1;
if (op == "and") return 2;
return INT_MAX; // true / false
}
// 构建表达式树(基于优先级,左结合)
ExpTreeNode* build(const vector<string> &tokens) {
stack<ExpTreeNode*> sta;
for (const string &t : tokens) {
int priority = getPriority(t);
ExpTreeNode* node = new ExpTreeNode(t);
node->priority = priority;
while (!sta.empty() && sta.top()->priority >= priority) {
ExpTreeNode* top = sta.top();
sta.pop();
int left_priority = INT_MIN;
if (!sta.empty()) {
left_priority = sta.top()->priority;
}
if (left_priority < priority) {
node->left = top;
} else {
sta.top()->right = top;
}
}
sta.push(node);
}
// 栈中剩余节点串成右斜树
ExpTreeNode* root = nullptr;
if (!sta.empty()) {
root = sta.top();
sta.pop();
ExpTreeNode* right = root;
while (!sta.empty()) {
root = sta.top();
sta.pop();
root->right = right;
right = root;
}
}
return root;
}
// 后序遍历求值
bool evaluateTree(ExpTreeNode* root) {
if (!root) return false;
if (root->symbol == "true") return true;
if (root->symbol == "false") return false;
bool leftVal = evaluateTree(root->left);
bool rightVal = evaluateTree(root->right);
if (root->symbol == "and") return leftVal && rightVal;
if (root->symbol == "or") return leftVal || rightVal;
return false; // 不可达
}
// 递归释放树节点
void releaseTree(ExpTreeNode* root) {
if (!root) return;
releaseTree(root->left);
releaseTree(root->right);
delete root;
}
};