优化逆波兰表达式(RPN)求值函数的高效实现咨询
优化RPN表达式求值的高效实现
你的当前实现存在两个核心问题:一是反复对vector<string>执行erase和insert操作,这类操作的时间复杂度为O(n),多次执行会让整体效率降到O(n²);二是逻辑上存在错误(比如用原表达式的索引操作副本、判断运算符的条件不准确、double转string的类型不匹配)。
标准且高效的RPN求值方式是使用栈结构,每个元素仅需遍历一次,栈的压入/弹出操作都是O(1),整体时间复杂度为O(m*n)(m是linspace的长度,n是RPN表达式的token数量),远优于当前实现。
优化后的代码实现
#include <stack> #include <vector> #include <string> #include <cctype> // 假设你的operations函数签名如下: // double operations(double left, double right, const std::string& op); std::vector<double> calculated_formula(const std::vector<std::string>& rpn_expression, const std::vector<double>& linspace) { std::vector<double> calculated_expression; calculated_expression.reserve(linspace.size()); // 预分配内存,避免多次扩容 for (double x_val : linspace) { std::stack<double> eval_stack; for (const std::string& token : rpn_expression) { if (token == "x") { // 直接压入当前x值,无需修改原表达式字符串 eval_stack.push(x_val); } else if (isdigit(token[0]) || (token.size() > 1 && token[0] == '-' && isdigit(token[1]))) { // 处理数字(包括负数) eval_stack.push(std::stod(token)); } else { // 处理运算符:弹出右操作数、左操作数 double right = eval_stack.top(); eval_stack.pop(); double left = eval_stack.top(); eval_stack.pop(); // 计算结果并压回栈 double result = operations(left, right, token); eval_stack.push(result); } } // 栈顶即为当前x值对应的表达式结果 calculated_expression.push_back(eval_stack.top()); } return calculated_expression; }
关键优化点说明
- 栈结构替代vector的erase/insert:栈的LIFO特性完美匹配RPN的求值逻辑,无需移动vector中的元素,大幅提升效率。
- 避免字符串修改:直接将
x对应的数值压入栈,不需要修改原RPN的字符串副本,节省内存和字符串转换的开销。 - 准确的token判断:通过检查token首字符是否为数字(或负号+数字)来识别数值,避免了原代码中
size()==1的错误判断(单个字符的数字会被误判为运算符)。 - 预分配内存:对
calculated_expression调用reserve,避免多次扩容带来的性能损耗。
内容的提问来源于stack exchange,提问作者Chetan Poudel
相关产品推荐
相关产品推荐

