2014-09-30 18 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

相關問題