第一版 字符串計(jì)算 架構(gòu)思路:
第一版 命名空間 BaseUtil.Compute —— 只是 BaseUtil 程序集 中的 一個(gè)子功能
第一版 抽象思想:
運(yùn)算分為 運(yùn)算符(IComputeSymbol + ComputeSymbolAttribute) + 函數(shù)(IComputeMethod + ComputeMethodAttribute)
使用 常用的 接口 + 特性 的方式 進(jìn)行插件擴(kuò)展
內(nèi)置插件
運(yùn)算符插件: + - * / % ^ LIKE > < >= <= = == === OR || AND && [?:]
函數(shù)插件: REPLACE LEN
基礎(chǔ)數(shù)據(jù)類型 的解析 為 代碼內(nèi)置:通過(guò)數(shù)據(jù)識(shí)別順序 判定類型
基礎(chǔ)數(shù)據(jù)類型: string double bool
基礎(chǔ)數(shù)據(jù)判定順序: string double bool
第二版 字符串計(jì)算 架構(gòu)思路:
第二版 命名空間 Laura.Compute —— 功能完全獨(dú)立
第二版 改進(jìn):
基礎(chǔ)數(shù)據(jù)類型: string double bool array
支持 數(shù)組 : 伴隨支持 IN 運(yùn)算符插件(第一版 的 IComputeSymbol IComputeMethod 無(wú)法擴(kuò)展 IN 語(yǔ)法)
重大思想變革: 取消 函數(shù)概念: 比如之前函數(shù) REPLACE(A, B, C) 思想轉(zhuǎn)變成 REPLACE {Array} —— 只要是 (A,B,C ...) 這樣的模式 統(tǒng)統(tǒng)被 認(rèn)定為 數(shù)組
取消函數(shù)概念 + 數(shù)組概念 造成的影響: 影響可能巨大,且可能導(dǎo)致的思想局限或者錯(cuò)誤暫時(shí)未知(2013-07-13)
取消參數(shù) 類型的 預(yù)設(shè)定: 第一版 因?yàn)椴恢?表達(dá)式 中,哪些是 參數(shù)表達(dá)式,所以需要 給表達(dá)式 提前設(shè)置 數(shù)據(jù)類型,所以 增加了使用復(fù)雜度。第二版 采用 參數(shù)表達(dá)式 自動(dòng)識(shí)別
第二版 抽象思想:
依然使用 接口 + 特性 的方式 進(jìn)行插件擴(kuò)展
核心思想: 類似 SQL 腳本的 語(yǔ)法模式
概念合并: 函數(shù)思想 合并 到 運(yùn)算符思想 中 —— 至此:函數(shù)也是一種 運(yùn)算符 [這是一個(gè) 思想合并的過(guò)程 : 即為 再抽象], 伴隨的是 接口 的 合并
————————————————————————————————————————————————————————————————
2013-07-16 00:21
————————————————————————————————————————————————————————————————
第二版 字符串計(jì)算 算法 已經(jīng)寫(xiě)完
算法完成 速度之快 主要是因?yàn)椋?br />>概念再抽象之后,核心思想 的簡(jiǎn)潔
>在并序運(yùn)算的代碼 直接復(fù)制 第一版的 并序運(yùn)算代碼 (ExpressSchema.cs 301-318 行代碼)
>很多插件 代碼 都是在 第一版插件代碼 基礎(chǔ)上 略做修改 而成,節(jié)省了不少時(shí)間
基本測(cè)試已經(jīng)通過(guò):
>運(yùn)行速度 達(dá)到 每秒 10000-12000 次左右(配置:CPU-I3 Momery-6G),遠(yuǎn)超 第一版 字符串計(jì)算算法(第一版 每秒 500-1000次左右)
>參數(shù)化 字符串計(jì)算 尚未測(cè)試:預(yù)想BUG應(yīng)該不大(因?yàn)?第二版 采用 先完全解析,再執(zhí)行 的思想,預(yù)期性能依然在 第一版 10倍以上)
算法亮點(diǎn):
>第二版語(yǔ)法 更人性化,除 可以省略的 this 關(guān)鍵字外,語(yǔ)法類似 SqlScript 如:[FSchoolName] == "孝感學(xué)院" AND [FStudentName] == "ShuXiaolong"
>第二版語(yǔ)法支持 索引,子屬性 超復(fù)雜表達(dá)式 如: this.[FSchools]["孝感學(xué)院"].[FClasses][1].[FClassName] (可省略 this)
>第二版語(yǔ)法 取消了 第一版語(yǔ)法 對(duì) 自定義屬性格式 的支持:所有 參數(shù)屬性 必須以 [] 括起來(lái)
>第二版語(yǔ)法 支持 插件擴(kuò)展 (第一版也支持),凡是 繼承 ICompute+ComputeExpressAttribute 的類 會(huì)被自動(dòng)識(shí)別為 算法插件
>第二版語(yǔ)法 支持 IN 關(guān)鍵字插件 (第一版語(yǔ)法 因?yàn)?概念思想 的局限,無(wú)法擴(kuò)展 IN插件) 如 \"ShuXiaolong\" IN (\"ShuXiaolong\",\"QuFuli\")"
算法用途:
>內(nèi)存檢索(當(dāng)然,速度 遠(yuǎn)遠(yuǎn)不及 SQL引擎 或 DataTable 的 檢索),在語(yǔ)法的 靈活性上 勝過(guò) DataTable 的內(nèi)存檢索計(jì)算
>動(dòng)態(tài)編程(接下來(lái) 有一個(gè) 概念器 的 流程引擎 的設(shè)計(jì)),讓動(dòng)態(tài)配置式 編程 更具有靈活性
第二版 和 第一版 算法插件 的 運(yùn)算優(yōu)先級(jí) 如下:
StringLengthComputeMethod LEN 1000000
StringReplaceComputeMethod REPLACE 1000000
PowComputeSymbol ^ 100000
MultiplyComputeSymbol * 10000
RemainComputeSymbol % 10000
DivideComputeSymbol / 10000
PlusComputeSymbol + 1000
MinusComputeSymbol - 1000
LikeEqualComputeSymbol LIKE 700
LessThanEqualComputeSymbol <= 685
GreaterThanEqualComputeSymbol >= 680
LessThanComputeSymbol < 675
GreaterThanComputeSymbol > 670
StrictEqualComputeSymbol === 610
EqualComputeSymbol == 605
BaseEqualComputeSymbol = 600
AndComputeSymbol AND 525
AndSignComputeSymbol && 525
OrComputeSymbol OR 520
OrSignComputeSymbol || 520
TernaryComputeSymbol ?: 100
InComputeMethod IN 未定(默認(rèn)為 0)代碼簡(jiǎn)單,先上運(yùn)行截圖:
編碼過(guò)程:
新建項(xiàng)目 基于 .Net 2.0:
在窗體上拖拽 文本框 作為顯示屏,并拖拽 按鍵:
為了節(jié)省代碼,所以每個(gè)按鈕 公用 btnInput_Click 事件;為了作為區(qū)分,所以 我們?cè)O(shè)置每個(gè) 按鈕的Tag 值:
在共用的按鈕事件中,我們進(jìn)行編碼:
1 private void btnInput_Click(object sender, EventArgs e) 2 { 3 Button currentButton = sender as Button; 4 if (currentButton != null && currentButton.Tag != null) 5 { 6 string input = currentButton.Tag.ToString(); 7 txtExpress.Text = txtExpress.Text + input; 8 } 9 }
最后計(jì)算:
計(jì)算過(guò)程,就交給 Laura.Compute 算法了:本算法為字符串計(jì)算算法,用本算法計(jì)算結(jié)果。
1 private void btnResult_Click(object sender, EventArgs e) 2 { 3 string express = txtExpress.Text ?? string.Empty; 4 if (string.IsNullOrEmpty(express) || string.IsNullOrEmpty(express.Trim())) 5 { 6 txtResult.Text = "ERROR:INPUT THE EXPRESS!"; 7 } 8 else 9 { 10 try 11 { 12 object result = ComputeHelper.Compute(txtExpress.Text); 13 txtResult.Text = (result ?? string.Empty).ToString(); 14 } 15 catch(Exception exp) 16 { 17 txtResult.Text = "ERROR:" + exp.Message; 18 } 19 } 20 }
程序代碼:
代碼極其簡(jiǎn)單,65行源碼。
1 using System; 2 using System.Windows.Forms; 3 using Laura.Compute; 4 5 namespace Laura.Calculator 6 { 7 public partial class MainForm : Form 8 { 9 public MainForm() 10 { 11 InitializeComponent(); 12 } 13 14 private void btnInput_Click(object sender, EventArgs e) 15 { 16 Button currentButton = sender as Button; 17 if (currentButton != null && currentButton.Tag != null) 18 { 19 string input = currentButton.Tag.ToString(); 20 txtExpress.Text = txtExpress.Text + input; 21 } 22 } 23 24 private void btnCancel_Click(object sender, EventArgs e) 25 { 26 string express = txtExpress.Text ?? string.Empty; 27 if (!string.IsNullOrEmpty(express)) 28 { 29 txtExpress.Text = express.Substring(0, express.Length - 1); 30 } 31 } 32 33 private void btnResult_Click(object sender, EventArgs e) 34 { 35 string express = txtExpress.Text ?? string.Empty; 36 if (string.IsNullOrEmpty(express) || string.IsNullOrEmpty(express.Trim())) 37 { 38 txtResult.Text = "ERROR:INPUT THE EXPRESS!"; 39 } 40 else 41 { 42 try 43 { 44 object result = ComputeHelper.Compute(txtExpress.Text); 45 txtResult.Text = (result ?? string.Empty).ToString(); 46 } 47 catch(Exception exp) 48 { 49 txtResult.Text = "ERROR:" + exp.Message; 50 } 51 } 52 } 53 54 private void btnClean_Click(object sender, EventArgs e) 55 { 56 txtExpress.Text = txtResult.Text = string.Empty; 57 } 58 59 private void linkAbout_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 60 { 61 AboutForm aboutForm = new AboutForm(); 62 aboutForm.ShowDialog(); 63 } 64 } 65 }
Ps.如果想擴(kuò)展 Laura.Compute 算法,在 任何程序集,任何命名空間,任何類名下 類似如下擴(kuò)展即可:
1 using System; 2 using Laura.Compute.Utils; 3 4 namespace Laura.Compute.Extend.MathMethod 5 { 6 [Serializable] 7 [ComputeExpress(Express = "{A} + {A}", Keywords = new[] { "+" }, Level = 1000, ComputeType = typeof(PlusComputeSymbol))] 8 public class PlusComputeSymbol : ComputeBase 9 { 10 public override object Compute(ExpressSchema expressSchema, object objOrHash) 11 { 12 object argObj1 = ArgumentsObject(0, expressSchema, objOrHash); 13 object argObj2 = ArgumentsObject(1, expressSchema, objOrHash); 14 15 if (ArgumentsType(0) == ExpressType.String || ArgumentsType(1) == ExpressType.String || argObj1 is string || argObj2 is string) 16 { 17 string arg1 = Tools.ToString(argObj1); 18 string arg2 = Tools.ToString(argObj2); 19 string value = arg1 + arg2; 20 return value; 21 } 22 else 23 { 24 double arg1 = Tools.ToDouble(argObj1); 25 double arg2 = Tools.ToDouble(argObj2); 26 double value = arg1 + arg2; 27 return value; 28 } 29 } 30 } 31 }
當(dāng)然,最后就是 本計(jì)算器源碼開(kāi)源,包括重磅 的 Laura.Compute 算法:http://pan.baidu.com/s/103Xic