我有一个这样的表达式/公式
std::string expr="((A>0) && (B>5 || C > 10))";
我做了一些研究,似乎如果A,B,C的值是已知的,通过在C++程序中嵌入Lua或Python,有eval
函数可以替代A,B和C并返回true
或false
。
但是当我不知道所有的值时会发生什么呢?假设A是已知的,它是-1。如果A为-1,则无论B或C的值如何,公式的计算结果都将为"false“。
我可以在事先不知道所有变量的情况下计算公式吗?例如,如果A是10,则查找B的值并再次重新求值是有意义的。我们如何解决这些问题呢?想法?
发布于 2017-04-28 15:45:45
我不知道任何现有的可用库来处理这个问题。
通常的方法是构建一个表达式树,并评估可能的情况-类似于编译器中的常量折叠:https://en.wikipedia.org/wiki/Constant_folding
其中一个重要方面是知道变量的允许值,因此允许的部分求值,例如,如果x*0
是整数或有限浮点数,则x*0
(和0*x
)是0
,但如果x
是IEEE浮点数(因为它可以是Nan或无穷大),或者x
是否可以是矩阵,因为[1,1]*0
是[0,0]
而不是标量0
,则不能对其进行评估。
发布于 2017-04-20 18:25:57
所以根据我对你问题的理解,你想要像这样的东西
if (A>0) {
B = getB();
C = getC();
if (B>23 || C==11)
explode();
}
也就是说,你的表达式必须被拆分,这样你才能处理已知值。
发布于 2017-04-20 19:33:43
你可以这样做:
class LazyValues():
def __init__(self):
self._known_values = {}
def __getitem__(self, var):
try:
return self._known_values[var]
except KeyError:
print("Evaluating %s..." % var)
return self._known_values.setdefault(var, eval(var))
def lazy_eval(expr, lazy_vars):
for var in lazy_vars:
expr = expr.replace(var, "lazy_values['%s']" % var)
# will look like ((lazy_value['A']>0) && (lazy_value['B']>5 || lazy_value['C'] > 10))
lazy_values = LazyValues()
return eval(expr)
lazy_eval("((A>0) and (B>5 or C > 10))", lazy_vars=['A', 'B', 'C'])
# Evaluating A...
# ....
# NameError: name 'A' is not defined
A = -1
lazy_eval("((A>0) and (B>5 or C > 10))", lazy_vars=['A', 'B', 'C'])
#Evaluating A...
#False
A = 5
B = 6
lazy_eval("((A>0) and (B>5 or C > 10))", lazy_vars=['A', 'B', 'C'])
# Evaluating A...
# Evaluating B...
# True
稍后会有更多细节...
https://stackoverflow.com/questions/43516792
复制相似问题