在C 中解決動態計算表達式的問題 如字符串 Sin 1 +Cos 2 執行並得出結果
分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!http://www.captainbed.net
前一陣公司老總要求我去重構一個同事的程序,裏面有各種計算公式,如下圖
這個公式的算法是這樣
0.058419 + 0.084612 * (log10(第二個文本框的值 / 第一個文本框的值)) + 0.3464 * 第三個文本框的值 + 0.00387 * 第四個文本框的值
另一個公式如下圖
公式是這樣
0.135 + 0.165 * log10(第一個文本框的值/第二個文本框的值)
這兩個公式用的是同一窗體,只是加載窗體的時候使用不同的公式而已,所以界面顯示的文本框數量,和一些說明文字不一樣.
每個公式需要的參數個數不一同,公式算法不一樣
我腦海裏第一個閃現的做法就是把這些信息整合進一個XML裏面進行配置,把計算的公式放進XML裏面,呵呵,但是這樣仍然解決不了我的問題
現在的公式成了字符串了,而不是程序裏面的變量.
由此我想到幾種解決方案,它們都屬於動態編譯,我找到一本英文資料,專門講C#的元編程<<Manning Metaprogramming in NET 2013>>
這本書提到幾種動態編譯的方法
1.CodeDom
2.Refection.Emit
3.Lambda表達式樹
4.DLR
4個我都看了一下,做了以下總結跟實踐
方法1
由此我找到兩個來自CodeProject的程序
http://www.codeproject.com/Articles/11939/Evaluate-C-Code-Eval-Function
http://www.codeproject.com/Articles/18004/Net-Expression-Evaluator-using-DynamicMethod
這兩個例子都非常好,尤其是第一個例子,演示了怎麽執行一段字符串寫的代碼,以及外部的代碼怎麽跟字符串寫的代碼交互,但是要完成我的需要,要寫的代碼不少!
方法2是操作IL中間語言,我看了一下它的生成代碼方式,有一定的靈活度,但要達到我這個程序的要求是太難,太煩,太麻煩!
方法3其生成代碼的過程跟方法2比較像,但要輕量級一些,沒那麽繁瑣,它主要是為了動態的生成一個Lambda表達式,但跟方法2一樣,不太方便
方法4DLR與動態語言交互,目前.net已經很好的支持了兩種腳本語言,Python和Ruby!看了一下Python的語法,感覺比較"輕便"!於是我把公式的計算翻譯成Python代碼並放入XML文件中,如下
<FormulaInfo MethodSmartPart = "EmpiricalCyq" FormulaName="陳元千相關經驗公式"
ParameterNameGroup = "地層原油粘度μo(mPa.s)|平均空氣滲透率K(mD)|有效孔隙度φ(f)|井網密度S(口/km²)"
ParameterRange = "0.5-154.0|4.8-8900.0|0.15-0.33|3.1-28.3"
ValidParameter = "0.5-154.0|4.8-8900.0|0.15-0.33|3.1-28.3"
Image = "陳元千相關經驗公式"
Code="def cal(): return 0.058419 + 0.084612 * (log10(float(ArrayCan[1].Text) / float(ArrayCan[0].Text))) + 0.3464 * float(ArrayCan[2].Text) + 0.00387 * float(ArrayCan[3].Text)" />
具體做法,我在我的另一篇文章裏面有
http://blog.csdn.net/lee576/article/details/18734253
關於IronPython的資料還有一篇寫的比較好:
C# 4.0 動態調用 IronPython
http://blog.csdn.net/goldworm2012/article/details/7621632
這個工作做完以後,我感覺方法1還是不錯的,但是跟方法4相比,它稍微"重"了一點,但是在執行其它任務時,它是最好的(比如執行一段由字符串寫的代碼),方法4用來做動態解析計算的時候最合適,代碼量少,清晰,並且Python在做科學計算方面比C#要強
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!http://www.captainbed.net
在C 中解決動態計算表達式的問題 如字符串 Sin 1 +Cos 2 執行並得出結果