『开源』一个简单的 字符串计算 算法开源
来源:互联网 发布:房树人绘画心理 知乎 编辑:程序博客网 时间:2024/06/03 23:42
算法开发原因:
自己一直在 配置化编程 方面努力,希望 项目复杂的功能可以用 简单的 配置来完成;
于是 在自己的网站中,使用了一个自己写的 数据库框架,为了给框架提速,于是就 想将 少于 5000 的数据表 进行全表缓存;
然后所有的 数据 就由框架 从缓存中 按照条件 检索——相当于 内存检索;
这时,问题就来了 —— 整个项目,Sql 脚本的 Where 条件,千变万化;
如何判断 某个对象 是否 符合 一个字符串的表达式,这就让我 头疼了;
于是经过搜索,得到: http://bbs.csdn.net/topics/230073145;
最终的解法 是 DataTable.Compute() 函数;还有一个 是 使用微软动态编译技术 的解决方案(这个才是真正无敌的方法)。
但是确有弊端:微软 动态编译技术 计算字符串表达式,即时计算 “1+1”,也需要 300ms,5000个数据的检索,这个是我所无法容忍的。
于是就想 写一个 字符串计算 的算法;
算法版本经历:
算法从去年5月完成,历时 2周业余时间,完成第一版;
今年7月开始,参与了几个 工作流项目的开发,觉着闹心:工作流 应该和 功能分开,结果我看到,代码中,业务代码和工作流代码 纵横交错;特别闹心;
于是就想 抽象一个流程设计器:让开发人员一心一意写业务代码,工作流的代码 全部使用配置,即时修改了流程,开发人员也不用 修改任何代码;
而 流程设计器 的的手稿过程中,发现 不可避免 的有一个环节:条件判断——这个非得使用 字符串计算算法;
于是 改版 第一版算法代码,得到今天的第二版 Laura.Compute;
算法亮点:
新版本 算法,字符串表达式 兼容 SQL脚本(和SQL脚本类似的 字符串格式);
新版本 算法,支持 动态参数(就像 SQL中 WHERE FName=@FName 一样);
新版本 支持 预分析,分析一次 多次执行(可用不同参数);
运算速度 达到 (分析+计算)*20000次 = 2000ms; 分析*1次+计算*20000次 = 150ms;
顺手实现了 字符串表达式 的内存检索(Word LIKE '%cat%'),50000单词,内存检索时间 800ms;
顺手实现了 字符串表达式 的 内存排序(Word DESC, ID ASC),50000单词,内存排序时间 2400ms;
算法思想:
算法用法:
使用代码:
<span style="font-family:Microsoft YaHei"><span style="font-size:12px">//分析一个 表达式,得到 表达式结构 对象ExpressSchema expressSchema3 = ExpressSchema.Create("\"ShuXiaolong\" IN (\"ShuXiaolong\",\"JiangXiaoya\")");//给定参数,计算这个 表达式结构 对象 在指定参数下 的运行结果object value = expressSchema3.Compute(null);Console.WriteLine(value);</span></span>计算结果:
其他用法:
以上只是 一个简单的 表达式:判断 某个 字符串 是否在 一个 数组中。
以下即为 其他 功能(这些功能 全都是 算法的 插件,任何开发人员都可以 在 任意程序集 中 扩展本算法):
插件名称: 关键字: 运算优先级:DateAddComputeMethodDATEADD1000000DateConvertComputeMethodCONVERTDATE1000000DateDiffComputeMethodDATEDIFF1000000DateFormatComputeMethodDATEFORMAT1000000DateNowComputeMethodGETDATE1000000DatePartComputeMethodDATEPART1000000GuidNewComputeMethodNEWID1000000StringLengthComputeMethodLEN1000000StringReplaceComputeMethodREPLACE1000000PowComputeSymbol^100000MultiplyComputeSymbol*10000RemainComputeSymbol%10000DivideComputeSymbol/10000PlusComputeSymbol+1000MinusComputeSymbol-1000LikeEqualComputeSymbolLIKE700LessThanEqualComputeSymbol<=685GreaterThanEqualComputeSymbol>=680LessThanComputeSymbol<675GreaterThanComputeSymbol>670StrictEqualComputeSymbol===610EqualComputeSymbol==605BaseEqualComputeSymbol=600AndComputeSymbolAND525AndSignComputeSymbol&&525OrComputeSymbolOR520OrSignComputeSymbol||520TernaryComputeSymbol?:100InComputeMethodIN未定(默认为 0)
支持 函数表达式,运算符表达式 ,这两种类型的表达式 用的是 同一个 抽象思想;
算法Demo展示:
计算对象:
<span style="font-family:Microsoft YaHei"><span style="font-size:12px"> Student stu01 = new Student { Name = "舒小龙", Number = "ShuXiaolong"}; Student stu02 = new Student { Name = "江小雅", Number = "JiangXiaoya" }; Student stu03 = new Student { Name = "舒珊", Number = "ShuShan" }; ExpressSchema expressSchema = ExpressSchema.Create("[Number] LIKE '%Shu%'"); bool result1_1 = (bool) expressSchema.Compute(stu01); bool result1_2 = (bool)expressSchema.Compute(stu02); bool result1_3 = (bool)expressSchema.Compute(stu03); Console.WriteLine(result1_1 + "|" + result1_2 + "|" + result1_3); ExpressSchema expressSchema2 = ExpressSchema.Create("[Name] + [Number]"); string result2_1 = (string)expressSchema2.Compute(stu01); string result2_2 = (string)expressSchema2.Compute(stu02); string result2_3 = (string)expressSchema2.Compute(stu03); Console.WriteLine(result2_1 + "|" + result2_2 + "|" + result2_3);</span></span>
内存排序:
<span style="font-size:12px"> DataSet dataSet = GetTableRecord(); //从数据库 读取 50000 个单词 DataTable dataWord = dataSet.Tables[0]; DateTime dt7 = DateTime.Now; IList listResult3 = ComputeHelper.Sort("[Word],[Comment]", dataWord.Rows); //用封装好的 排序函数 排序 DateTime dt8 = DateTime.Now; Console.WriteLine("ComputeHelper.Sort()排序时间:" + (dt8 - dt7).TotalMilliseconds); Console.WriteLine(listResult3);</span>
内存筛选:
<span style="font-size:12px"> DataSet dataSet = GetTableRecord(); //从数据库 读取 50000 个单词 DataTable dataWord = dataSet.Tables[0]; DateTime dt7 = DateTime.Now; IList listResult3 = ComputeHelper.Filter("[Word] LIKE '%cat%'", dataWord.Rows); //用封装好的 筛选函数 筛选 DateTime dt8 = DateTime.Now; Console.WriteLine("ComputeHelper.Filter()筛选时间:" + (dt8 - dt7).TotalMilliseconds); Console.WriteLine(listResult3 + " 数目:" + listResult3.Count);</span>
算法源代码:
源码在线阅读
Ps. 最好是能将源码 发不到某个 网络版本控制器上,但是不知道 如何操作,也不知道哪个 哪个平台 有 SVN的版本控制器;
如果哪位有好的 网络版本控制器,希望推荐一哈——还是放到 版本控制器中 开源 比较好;
- 『开源』一个简单的 字符串计算 算法开源
- 一个简单的JavaScript日期计算算法
- 一个计算平方根的简单算法
- 简单的字符串算法
- 计算一个字符串的MD5
- (算法)计算一个字符串在另一个字符串中出现的次数
- 一个比较字符串和一个计算N个数字阶乘之和的算法
- 对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
- 输入一个只包含个位数字的简单四则表达式字符串,计算该表达式的值
- 输入一个只包含个位数字的简单四则运算表达式字符串,计算该表达式的值
- 新手学算法_05_一个简单的字符串匹配的算法
- 递归算法计算一个字符串中最大的连续字符个数
- 用递归算法计算一个字符串中最大的连续字符个数
- 一天一个算法题-简单的-递归-计算a+aa+aaa+...+aaaa...a的数值
- 一天一个算法题-简单的-递归-计算球的落下
- 算法分析的一个简单的例子(运行时间计算)
- 一个简单的字符串类
- 简单的字符串匹配算法
- HUNNU11392:Candy Store (完全背包)
- MFC打印位图 (BMP)
- 美国七大IT公司雇员的母校分布情况(包括大陆院校)
- VBA 统计合并后的单元格内容方法
- 新浪微博请求数据出错(Android Volley Https证书不信任)的解决方案
- 『开源』一个简单的 字符串计算 算法开源
- MFC 语音播放
- 1
- Ringo.js字符集问题解决
- 【人脉求职】找工作的路上,师哥师姐为什么不想帮你?
- 输入一个字符串,取出其中的整数(实现代码)
- 目标
- 循环单链表的合并
- 动态内存