我试图将数学表达式转换为RPN,然后对它们执行符号化的区分,但是我仍然被一些函数所困,比如sin() cos() tan().ln() sqrt()等。我的表达式解析器只适用于更简单的情况,比如RPN wiki中的一个:
3+4*2/(1-5)^2^3产生以下情况:
342*15-23^^/+然而,当涉及到一个更复杂的公式时,比如:
sin(2*x^2+6)-(cos(x)/(1-x))我也不能手工创建RPN。我目前工作的最低限度的解决方案再次实现,根据算法定义的Wiki上的分流-场算法。
std::string ParseExpression(const std::string &expr) {
std::string ops = "-+/*^";
std::stringstream output;
std::stack<int> stack;
typedef std::string::const_iterator StringIterator;
for (StringIterator TOKEN = expr.cbegin(), END = expr.cend(); TOKEN != END; ++TOKEN) {
const char c = *TOKEN;
size_t idx = ops.find(c);
if (idx != std::string::npos) {
if (stack.empty()) {
stack.push(idx);
}
else {
while (!stack.empty()) {
int prec2 = stack.top() / 2;
int prec1 = idx / 2;
if (prec2 > prec1 || (prec2 == prec1 && c != '^')) {
output << ops[stack.top()];
stack.pop();
}
else {
break;
}
}
stack.push(idx);
}
} else if (c == '(') {
stack.push(-2);
} else if (c == ')') {
while (stack.top() != -2) {
char op = stack.top();
stack.pop();
output << ops[op];
}
stack.pop();
} else {
output << c;
}
}
while (!stack.empty()) {
output << ops[stack.top()];
stack.pop();
}
return output.str();
}我如何在RPN公式中包括三角函数和其他函数,并正确地处理它们?
发布于 2014-06-18 07:27:55
RPN对函数(包括三角函数)的工作原理与对运算符的工作原理相同。对于三角学,只有一个参数(与运算符不同,后者通常有两个参数)。
你的例子
sin(2*x^2+6)-(cos(x)/(1-x))就会变成
2x2^*6+_sin_x_cos_1x-/-为了清晰起见,我在前后强调了sin和cos函数。
更抽象一点,如果你认为运算符是双参数函数,三角学是单参数函数,那么它可能会更有意义--函数总是在其参数之后出现,并按堆栈弹出顺序计算前面的args (最后,先出)。将运算符更改为函数(将"b“作为二进制,"u”表示一元)将给我们提供以下内容。RPN说,对于任何具有"b“(两个参数)的东西,前面的两个args都是在函数中计算的。对于以"u“结尾的函数(一个参数),计算前面的参数。
2x2_powb__multb_6_plusb__sinu_x_cosu_1x_minusb__divb__minusb_https://stackoverflow.com/questions/24279027
复制相似问题