2013-08-24 28 views
0

我米拆分式字符串"*/+-()"作爲我的圖案(例如。a*b+c被串)和I m到處在輸出列表作爲(a b c)其中abc是變量幷包含一些值,如510,15分裂式,並再次再生和reevaluateing式

我需要的是:我應該能夠直接替換變量中的值並評估表達式。

該公式取自用戶並隨時更改。所以如果用戶輸入(a/b),應該用實際值(5/10)自動替換它,然後返回結果0.5。

的公式從變量數目有限(例如爲abc。)形成,並且它可以使用+-*/()作爲運算符。

問題是,在分解變量後,我無法用它們的值替換它們或評估方程。請儘可能以簡短的表達方式幫助我完成這項任務。提前致謝。

+0

你爲什麼不簡單地把字符串傳給'expr'?它將進行必要的替換並返回操作的結果。 – Jerry

+0

輸入就像a * b + c。我需要將(a b c)列表轉換爲($ a * $ b + $ c)之類的東西。這就是爲什麼它很複雜。 –

+0

如果你有一個數組呢?正如'a(b)+ c'?你會如何區分它與'a(b * d)+ c'?第一個通常可以變成'$ a(b)+ $ c'或'$ a($ b)+ $ c',而第二個可以是'$ a($ b * $ d)+ $ c'或'$ a ($ b * d)+ $ c'或'$ a(b * $ d)+ $ c'或'$ a($ {b * d})+ $ c'或'$ a(b * d)+ $ C' ...? – Jerry

回答

0

這不是在所有的複雜:

首先,用一個Tcl變量替換所有的變量(一個坦然$)。
你必須小心,不要用$sin($a)或類似的東西代替sin(a)

regsub -all -inline {[a-z]+(?![a-z\(])} $input 

實施例:

set input {a*b+c+sin(d)} 
regsub -all -inline {[a-z]+(?![a-z\(])} $input 

將產生$a+$b*$c+sin($c),其可以被傳遞給expr
如果您需要變量名稱,只需在該表達式中使用regexp即可。

+0

問題是,要完成這個替換的循環,我們沒有方程a * b + c。我們只有(a b c)。 bcz在進入循環之前發生分裂。所以循環只知道列表(a b c)。運營商必須從外部取得。 @Johannes –

+0

你可以顯示代碼嗎? –

+0

等等,我應該怎麼知道'a b c'應該指'a * b + c'還是'a-b/c'? (或者:運營商在哪裏?) –

0

如果知道變量名稱和他們都不是其他任何你使用前綴,你可以很容易地變換表達這樣的:

set a 1; set b 2; set c 3 
set e "a*b+c" 
set value [expr [string map {a $a b $b c $c} $e]] 
puts "$e = $value" 

注:沒有括號圍繞第三行的表達式。這是因爲您正在執行表達式的運行時生成,因此您希望避免這種安全。

可自動生成的映射:

set a 1; set b 2; set c 3 
set e "a*b+c" 
set vars {a b c} 
set value [expr [string map [regsub -all {\w+} "& $&"] $e]] 
puts "$e = $value" 

但是,如果你有前綴和其他類似的東西,你需要一個更復雜的變換:

# Omitting the variable setup and print at the end... 
proc replIfRight {vars word} { 
    if {$word in $vars} {return \$$word} else {return $word} 
} 
set value [expr [subst [regsub -all {\w+} [string map {[ \[ $ \$ \\ \\\\} $e] {[replIfRight $vars &]}]]] 

你絕對不要指望自己想出這樣一件可怕的事情!