1. 程式人生 > >在C 中解決動態計算表達式的問題 如字符串 Sin 1 +Cos 2 執行並得出結果

在C 中解決動態計算表達式的問題 如字符串 Sin 1 +Cos 2 執行並得出結果

翻譯 tro res min dsm ram 文件 edit 很好

分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!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

非常好,可以動態編譯C#的代碼,比如在一個文件框裏寫MessageBox.Show(......)然後讀取文本框裏的代碼執行,就可以彈出一個文本框,如下圖

技術分享圖片

技術分享圖片

由此我找到兩個來自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 執行並得出結果