我需要编写一个可以在运行时获取if语句的函数(例如用户输入或数据文件)。理想情况下,它应该能够解决一个复杂的表达式:
a && ( b || !c || ( d && e ) )
我想我需要的是一个递归函数(一个自称的函数)。当然,该函数需要返回 true 或 false 。
由于上述示例的复杂性,函数不仅需要循环遍历各个条件,还需要了解运算符,知道评估它们的顺序,并且最好将它们的优先级设置为速度(例如,在示例中) ,如果 a false ,则无需评估该语句的其余部分。)
有没有人有任何想法?
答案 0 :(得分:3)
一种解决方案是使用分流码算法将表达式转换为RPN,然后将其评估为RPN(因为RPN比中缀更容易评估)。第一部分,转换为RPN(伪代码):
while (tokens left) {
t = read_token();
if (t is number) {
output(t);
} else if (t is unary operator) {
push(t);
} else if (t is binary operator) {
r = pop();
if (r is operator and precedence(t)<=precedence(r)) {
output(r);
} else {
push(r);
}
push(t);
} else if (t is left parenthesis) {
push(t);
} else if (r is right parenthesis) {
while ((r = pop()) is not left parenthesis) {
output(r);
if (stack is empty) {
mismatched parenthesis!
}
}
if (top() is unary operator) {
output(pop());
}
}
}
while (stack is not empty) {
if (top() is parenthesis) {
mismatched parenthesis!
}
output(pop());
}
read_token
从输入队列中读取令牌output
将值插入输出队列push
将值推入堆栈(您只需要一个)pop
从堆栈中弹出一个值top
在不弹出RPN评估更简单:
while (tokens left) {
t = read_token();
if (t is number) {
push(t);
} else if (t is unary operator) {
push(eval(t, pop()));
} else if (t is binary operator) {
val1 = pop();
val2 = pop();
push(eval(t, val1, val2));
}
}
result = pop();
read_token()
从上一步生成的RPN队列中读取值eval(t, val)
使用操作数t
评估一元运算符val
eval(t, val1, val2)
使用操作数t
和val1
评估二元运算符val2
result
是表达式的最终值如果所有运算符都是左关联的并且没有使用任何函数,则此简化算法应该有效。请注意,不需要递归,因为我们使用自己的堆栈实现。 有关示例和更多信息,请参阅Rosetta Code on Shunting-yard和Rosetta Code on RPN