2014-09-30 26 views
1

作为赋值的一部分,我创建了一个函数,它接受一个字符串,它是一个等式。这里是一个例子:48 + 6x6/3 = 6x8-9x2。计算函数采用等号的一边并对其进行评估。我不太关心分解方程式。我相信我可以将它与s[:s.find("=")]分开。创建一个以字符串形式给出的方程并计算它的函数

我的主要问题是计算功能本身。我会发布到目前为止我所在的位置。注释掉的部分是我试图处理两位数的东西,但我无法找出合理的方法来做到这一点。我想要一些帮助来思考这个问题。

我被告知不使用eval因为等式做EVAL“2 + 3 * 5-11/2 * 88 + 153”将不容易因操作者的优先级 - 或缺乏。我的程序不应遵守正常的运营商优先规则。相反,它应该纯粹从左到右进行评估。

​​93590046

编辑此工程的单个数字。也许我们可以这样来使用eval是非常危险的多个数字

def compute(s): 
    result = int(s[0]) 
    op = 0 
    a = 1 
    while a < len(s): 
     if s[a] == '/': 
     result /= int(s[a + 1]) 
    elif s[a] == '+': 
     result += int(s[a + 1]) 
    elif s[a] == '*': 
     result *= int(s[a + 1]) 
    elif s[a] == '-': 
     result -= int(s[a + 1]) 
    a += 1 
    return int(result) 
+0

对我仍然不清楚。 'eval'将简单地计算输入中的方程。如果输入不清楚,就像在你的例子中一样,编写算法根本无济于事。 – Dunno 2014-09-30 21:09:24

+0

在这个问题上,评估是严格的从左到右。由于我强制从左到右,因此需要删除eval。所以像'eval(str(eval(“2 + 3”))+“* 5”)这样的东西对于更长的方程将变得非常讨厌。 – darksoulsfan 2014-09-30 21:17:46

+0

只要你坚持'*'乘以乘法,使用'eval'实际上是微不足道的。这听起来更像是你需要编写正确处理运算符优先级的代码,以便你正确评估'6 + 3 * 9'为'6 +(3 * 9)'而不是简单地从左到右处理它(错误地)作为'(6 + 3)* 9' – chepner 2014-09-30 21:25:51

回答

3

工作,如果你接受字符串从不受信任的输入来评价。例如假设被评估的字符串是"os.system('rm -rf /')"?它会真正开始删除您计算机上的所有文件。

所以,你可以用python的内部compiler解析它:

import compiler 
eq="48+6*6/3" 
ast= compiler.parse(eq) 

>>> compiler.parse(eq) 
Module(None, Stmt([Discard(Add((Const(48), Div((Mul((Const(6), Const(6))), Const(3))))))])) 
>>> 

您也可以使用sympy这是一个Python库符号数学。它旨在成为一个全功能的计算机代数系统(CAS),同时保持代码尽可能简单,以便易于理解和扩展。 SymPy完全用Python编写,不需要任何外部库。

+0

好吧,但是你必须使用equal来拆分公式,然后比较两个编译器的结果值。 – 2014-09-30 21:41:54

+1

我想给最好的方法!不是简单的方法! – Kasramvd 2014-09-30 21:52:52

+0

并不是说这很糟糕,它只是根据你现在更加完整的答案来帮助你。感谢compiler.parse()btw,我不知道它! – 2014-09-30 21:55:42

相关问题