算法开发原因:
自己一直在 配置化编程 方面努力,希望 项目复杂的功能可以用 简单的 配置来完成;
于是 在自己的网站中,使用了一个自己写的 数据库框架,为了给框架提速,于是就 想将 少于 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;
算法思想:
算法用法:
使用代码:
//分析一个 表达式,得到 表达式结构 对象
ExpressSchema expressSchema3 = ExpressSchema.Create("\"ShuXiaolong\" IN (\"ShuXiaolong\",\"QuFuli\")");
//给定参数,计算这个 表达式结构 对象 在指定参数下 的运行结果
object value = expressSchema3.Compute(null);
Console.WriteLine(value);
计算结果:
其他用法:
以上只是 一个简单的 表达式:判断 某个 字符串 是否在 一个 数组中。
以下即为 其他 功能(这些功能 全都是 算法的 插件,任何开发人员都可以 在 任意程序集 中 扩展本算法):
插件名称: 关键字: 运算优先级:
DateAddComputeMethod DATEADD 1000000
DateConvertComputeMethod CONVERTDATE 1000000
DateDiffComputeMethod DATEDIFF 1000000
DateFormatComputeMethod DATEFORMAT 1000000
DateNowComputeMethod GETDATE 1000000
DatePartComputeMethod DATEPART 1000000
GuidNewComputeMethod NEWID 1000000
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 未定(默认为 0)
支持 函数表达式,运算符表达式,这两种类型的表达式
用的是 同一个 抽象思想;
算法Demo展示:
计算对象:
Student stu01 = new Student { Name = "舒小龙", Number = "ShuXiaolong"};
Student stu02 = new Student { Name = "瞿福丽", Number = "QuFuli" };
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);
内存排序:
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);
内存筛选:
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);
算法源代码:
源码在线阅读
Ps. 最好是能将源码 发不到某个 网络版本控制器上,但是不知道 如何操作,也不知道哪个 哪个平台 有 SVN的版本控制器;
如果哪位有好的 网络版本控制器,希望推荐一哈——还是放到 版本控制器中 开源 比较好;
分享到:
相关推荐
java-string-similarity, 各种字符串相似性和距离算法 java-string-similarity 实现不同字符串相似度和距离度量的库。 目前已经实现了许多算法( 包括Levenshtein编辑距离和 sibblings,jaro winkler,最长公共子序列...
“此算法使用子字符串的第一个,最后一个,mid1和mid2索引进行模式搜索。” 时间和空间复杂度:对于长度为n的文本和长度为m的子字符串。 在最佳情况下,时间复杂度为O(m / 4),在最坏情况下,时间复杂度为O(n –...
duovia-fuzzystrings, .NET的模糊字符串算法 duovia-fuzzystrings DuoVia.FuzzyStrings获取NuGet软件包包. NET.的模糊字符串算法集合这部分来自多个开放源代码。 查看用于属性的单独算法类。开发人员可以能希望利用...
字符串匹配算法:字符串匹配算法用于在一个字符串(文本)中查找一个子串(模式)的出现位置。常见的字符串匹配算法包括暴力匹配、KMP算法、Boyer-Moore算法等。 这些是计算机科学中常见的算法类型,每种算法都有...
基于压缩后缀数组实现的一个字符串搜索库,用压缩后缀数组算法实现了一个简单核心的搜索开源库,可以扩展。
WordSort是一种用c#编写的算法,专门用于线性复杂度的字符串排序。 基于部分哈希的方法,比使用比较的经典算法提供更高的性能。 WordSort包含一个控制台应用程序,可轻松直观地用于评估和比较算法性能。 仅提供顺序...
clj-fuzzy, 一种处理模糊字符串和语音的算法集合 clj模糊clj模糊是一个本机Clojure库,提供了处理模糊字符串和语音的著名算法的Collection 。它可以在 Clojure 。ClojureScript 。客户端JavaScript和 Node.js. 中...
Cape 算法很弱,因为它的设计没有充分考虑Kerckhoff 原则或“一个人应该在假设敌人会立即完全熟悉它们的情况下设计系统”,而“通过默默无闻的安全”原则显然是不适用于开源软件。此外,还没有考虑到攻击者可能会...
“此算法使用子字符串的第一个和最后一个索引进行模式搜索。” 时间和空间复杂度:对于长度为n的文本和长度为m的子字符串。 在最佳情况下,时间复杂度为O(m / 2),在最坏情况下,时间复杂度为O(n –(m / 2))...
一个简单的TF-IDF算法算法中文文本这是一个简单的TF-IDF算法,该算法使用python开源软件包“ JIEBA”将汉字字符串切成单个单词,然后使用sklearn中的TfidfTransformer来计算每个设置中每个单词的TF-IDF值。...
新的字符串搜索算法。 许可证: ---------- 本项目中提供的所有程序/软件均在 APACHE LICENSE, VERSION 2.0 下发布。 可以在此处找到许可证详细信息:https://www.apache.org/licenses/LICENSE-2.0。 本许可的某些...
bm 是一个 Bentley/McIlroy 长字符串压缩算法的 Go 语言实现版本。
内容是几个简单的算法题的个人解法: 1 倒序输出数字 123 -> 321 2 比较两个版本数字的大小 0.1 < 1.1 < 1.3 <13.3 3 找出小于n的所有质数 4 上n个台阶,每次可以上1或者2个台阶,问共有多少种走法? 5 ...
.NET的模糊字符串算法的集合。 这部分来自多个开源。 有关归因,请参见各个算法类。 开发人员可能希望利用此libray或人为的字符串比较扩展方法中包含的一种或多种算法,如下所示: bool isEqual = input . ...
1. 根据输入字符串识别编码模式; 2. 根据输入字符串长度选择合适的QRcode版本; 3. 将编码转换为二进制位流表示为数据码字; 4. 使用多项式生成纠错码; 5. 将数据码和纠错码排列到二维码上; 6. 加入定位符号、...
特点计算字符串的 simhash通过构建智能索引来计算所有字符串之间的相似性,因此可以处理大数据使用使用输入文件和输出文件运行 Maininputfile 的格式(参见 src / test_in):一个文件每行用 utf8 字符集outputfile...
GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....
设定字符串为“张三,你好,我是李四” 产生张三的密钥对(keyPairZhang) 张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节 通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后...
GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....
开源学习吧,大家觉得有什么可以改的可以私信或者私聊我喔,我里面也有一点小bug,目前不知道怎么解决,有大佬可以解释的话,万分感谢捏。终于搞懂KMP了,不容易呀,哈哈哈哈!