表示式求值是乙個很有意思的技術話題,國內外討論這個話題的技術人員很多,也有非常多的實現方案。倒不是說這個問題很難解決,只是說它提供了很好的話題,讓各路高手使用自己的手段來解決問題,百家爭鳴,各展所長。該話題也提供了乙個非常好的想像空間讓大家一起討論技術討論方案,也是乙個資料結構教程中的經典教育案例。
一般可以使用堆疊,表示式樹(.net)之類的方法解決,但如果要實現比較複雜的表示式求值,如資料方法求值,字串,是否求值,方法計算等等,那就不是教學案例了,應該是乙個編譯器的問題了。即是編寫乙個編譯器來計算表示式的值。這似乎就沒那麼簡單,也不是一般技術活了。
複雜的表示式求值怎樣解決
幸好,.net已經有了動態編譯的介面,即在執行時,直接將一堆字元編譯為機器碼並可以執行。這為複雜的表示式求值提供了乙個手段。.net提供了system.codedom命名空間,該空間下有多個編譯相關的類,使用這些類就可以實現動態的編譯和執行。不過這個編譯的過程與vs2008等,事實上是一樣的,如果**簡單編譯就是快,如果**複雜就很慢,生成的內容也很慢。這是因為.net是預編譯機制,編譯好之後才進行呼叫或計算,如果要馬上編譯馬上計算,那執行的效率就不會高了。
執行效率不高,如果在大型高併發運算中,是乙個不可以忽視的問題,但如果只是小量計算,或者使用的是客戶端資源進行計算,不影響伺服器的效能的話,動態編譯也是個非常可靠的方法。您可以在**中實現任何的功能,所有.net的api,方法和類,你都可以使用,而且編譯解釋引擎非常的可靠,那著實是不可多得的好東西。如果你要動態編譯的內容是固定的,而不是每一次都會發生變化的表示式,那就更加好了,編譯出來的類和方法都可以快取起來,下一次就可以直接使用了,效率與平常寫**是一樣的。
使用.net動態編譯器來解釋計算公式,不失為一種可行,穩定,可靠的表示式求值解決方案,不過如果要直接使用.net動態編譯器,還要生成乙個類,寫一部分**,如using,class等等,還要有一定的擴充套件性,那就不一定個個人都想搞那麼多了。使用ckrule可以大大簡化這個過程。
序號需求特點
ckrule使用方法
1不需要固定的物件,方法,只要解釋表示式
新建乙個規則包*.ckp,直接傳入表示式引數。
2要有固定物件,內建方法
在新建的規則包中,增加這些方法,並直接呼叫。
在您的程式中實現表示式求值
程式執行截圖:
**實現:
if (string.isnullorempty(txtword.text.trim()))
trycatch (exception exp)
只使用了乙個最簡單的介面,rulefacade類的testpool方法。並傳入規則包的名稱和表示式內容,您就可以使用非常豐富的表示式求值。
但之前已經提到,.net動態編譯的機制,注定這種動態求值的方案並不是很適應於大型的高併發計算中,不過如果是使用客戶端的桌面資源或對併發要求不高的情況下,還是很好用的。
字尾表示式實現表示式求值
看到別人寫的乙個表示式求值程式,想到很久之前寫的乙個。中間有個字串轉數值型,可以用stringstream來實現或者c語言裡面的strtod直接得到 include include include include includeusing namespace std class data doubl...
表示式求值(c 實現)
今天寫了乙個表示式求值的程式。基本功能為 輸入乙個表示式比如23 34 21 56 45 1 然後程式求出結果。而且按照四則運算的優先順序,同時支援括號。下面是程式執行的畫面 程式的難點在於把乙個字串分解為運算元和操作符並能正確處理各個操作符的優先順序,特別是有括號的情況。本程式主要採用了傳統的方法...
ACM 表示式求值實現
時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 acm隊的mdd想做乙個計算器,但是,他要做的不僅僅是一計算乙個a b的計算器,他想實現隨便輸入乙個表示式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。比如輸入 1 2 4 程式就輸出1.50 結果保留兩位小數 輸入...