『开源』一个简单的 字符串计算 算法开源

算法开发原因:

自己一直在 配置化编程 方面努力,希望 项目复杂的功能可以用 简单的 配置来完成;

于是 在自己的网站中,使用了一个自己写的 数据库框架,为了给框架提速,于是就 想将 少于 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>

计算结果:




其他用法:

以上只是 一个简单的 表达式:判断 某个 字符串 是否在 一个 数组中。

以下即为 其他 功能(这些功能 全都是 算法的 插件,任何开发人员都可以 在 任意程序集 中 扩展本算法):

	插件名称:                                      关键字:                运算优先级:
	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展示:

计算对象:

<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的版本控制器;

如果哪位有好的 网络版本控制器,希望推荐一哈——还是放到 版本控制器中 开源 比较好;


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenSAL1.1 包含了算法导论中所有数据结构和算法以及其他内容,本资源为该算法库的静态链接库 内容如下(*号表示1.1版本新增内容): 数据结构:一般堆、二项堆、斐波那契堆、红黑树、通用散列(采用全域散列和完全散列技术)、不相交集合、任意维数组、高维对称数组。 图论算法(兼容有向图,无向图):广度和深度优先遍历、确定图是否存在回路、拓扑排序、强连通分支、欧拉环(欧拉路径)、最小生成树(Kruskal、Prim)、单源最短路径(3种)、每对顶点间最短路径(2种)、最大流(2种)等等。 代数算法:霍纳法则计算多项式和、矩阵乘法(2种)、方阵的LUP分解、解线性方程组(2种)、矩阵求逆(2种)、求伪逆矩阵(2种)、解正态方程组(2种)、最小二乘估计(2种)、多元最小二乘估计*、快速傅里叶变换、快速傅里叶逆变换、多维快速傅里叶变换、多维快速傅里叶逆变换、快速向量求卷积(单变量多项式乘积)、快速张量求卷积(多变量多项式乘积)、多项式除法*、快速方幂和算法。 序列算法:最长公共子序列、KMP序列匹配*、键值分离排序。 数论算法:大数类(兼容浮点数、整数、与内置类型兼容运算)*、RSA加解密系统*、解同余方程*、孙子定理解同余方程组*、Miller_Rabin素数测试(产生大质数)*、随机数(实数、大数)*、欧几里得算法*。 计算几何算法:确定任意一对线段是否相交*、凸包*、最近点对*。 运筹学:线性规划(单纯形法)*、分配问题*、最优二度子图*、多01背包问题*

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值