表达式求值的实现

表达式求值是一个很有意思的技术话题,国内外讨论这个话题的技术人员很多,也有非常多的实现方案。倒不是说这个问题很难解决,只是说它提供了很好的话题,让各路高手使用自己的手段来解决问题,百家争鸣,各展所长。该话题也提供了一个非常好的想像空间让大家一起讨论技术讨论方案,也是一个数据结构教程中的经典教育案例。

一般可以使用堆栈,表达式树(.Net)之类的方法解决,但如果要实现比较复杂的表达式求值,如数据方法求值,字符串,是否求值,方法计算等等,那就不是教学案例了,应该是一个编译器的问题了。即是编写一个编译器来计算表达式的值。这似乎就没那么简单,也不是一般技术活了。

复杂的表达式求值怎样解决

幸好,.net已经有了动态编译的接口,即在运行时,直接将一堆字符编译为机器码并可以运行。这为复杂的表达式求值提供了一个手段。.net提供了System.CodeDom命名空间,该空间下有多个编译相关的类,使用这些类就可以实现动态的编译和执行。不过这个编译的过程与VS2008等,事实上是一样的,如果代码简单编译就是快,如果代码复杂就很慢,生成的内容也很慢。这是因为.net是预编译机制,编译好之后才进行调用或计算,如果要马上编译马上计算,那运行的效率就不会高了。

运行效率不高,如果在大型高并发运算中,是一个不可以忽视的问题,但如果只是小量计算,或者使用的是客户端资源进行计算,不影响服务器的性能的话,动态编译也是个非常可靠的方法。您可以在代码中实现任何的功能,所有.net的api,方法和类,你都可以使用,而且编译解释引擎非常的可靠,那着实是不可多得的好东西。如果你要动态编译的内容是固定的,而不是每一次都会发生变化的表达式,那就更加好了,编译出来的类和方法都可以缓存起来,下一次就可以直接使用了,效率与平常写代码是一样的。

使用.net动态编译器来解释计算公式,不失为一种可行,稳定,可靠的表达式求值解决方案,不过如果要直接使用.Net动态编译器,还要生成一个类,写一部分代码,如using,class等等,还要有一定的扩展性,那就不一定个个人都想搞那么多了。使用CKRule可以大大简化这个过程。


序号
需求特点
CKRule使用方法

1
不需要固定的对象,方法,只要解释表达式
新建一个规则包*.ckp,直接传入表达式参数。

2
要有固定对象,内置方法
在新建的规则包中,增加这些方法,并直接调用。


在您的程序中实现表达式求值

程序运行截图:

代码实现:

if (string.IsNullOrEmpty(txtWord.Text.Trim()))

{

MessageBox.Show("脚本内容不能为空!");

}

try

{

var _result = new RuleFacade().TestPool<object>(FrmRulePoolSet.RuleInstName, txtWord.Text);

txtResult.Text = "结果是:" + _result;

}

catch (Exception exp)

{

MessageBox.Show(exp.Message);

}

只使用了一个最简单的接口,RuleFacade类的TestPool方法。并传入规则包的名称和表达式内容,您就可以使用非常丰富的表达式求值。

但之前已经提到,.net动态编译的机制,注定这种动态求值的方案并不是很适应于大型的高并发计算中,不过如果是使用客户端的桌面资源或对并发要求不高的情况下,还是很好用的。

源代码下载 : http://www.ckrule.com/cn/demo.html

表达式求值的实现

时间: 2024-10-21 20:01:25

表达式求值的实现的相关文章

四则运算表达式求值 OpenJ_Bailian - 4132

四则运算表达式求值 OpenJ_Bailian - 4132 题意:设计一个计算器,实现+-*/以及()的表达式运算求值. 栈的应用,这学期学数据结构,手写了栈练一下~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; //最大表达式长度 4 5 template <typename T> 6 class Stack; 7 8 template <typename T> 9

表达式求值

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,近期又学会了一些简单的函数求值,比方,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式. 如果表达式能够简单定义为: 1. 一个正的十进制数 x 是一个表达式. 2. 假设 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

四则运算表达式求值の各种心碎

实验三---四则运算表达式求值 一.基本要求: ( 1 ) 利用二叉树后序遍历来实现表达式的转换,同时可以使用实验三的结果来求解后缀表达式的值. ( 2) 输入输出格式: 输入格式:在字符界面上输入一个中缀表达式,回车表示结束. 请输入表达式: 输入一个中缀表达式 输出格式:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后 缀表达式中两相邻操作数之间利用空格隔开:如果不正确,在字符界面上输出表达式错误提示. 逆波兰表达式为: 输出逆波兰表达式 运算结果为:输出运算后的结果 测试数据

lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值

题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"]

使用逆波兰式进行表达式求值

中缀表达式及后缀表达式图解中说明了使用逆波兰式进行表达式求值的方法,这里使用C++进行实现.实现和原理讲解有一点不同,需要进一步进行细化. 关于将中缀表达式转换成后后缀表达式的规则: 规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分:若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止. 上面的规则转换成下面的执行规则: 1.遇到操作数:直接输出(添加到后缀

序列点在C语言表达式求值中的作用

摘要: 本文开创性地分析了序列点在C语言表达式求值中的作用:序列点左边的操作数要先于其右边的操作数求值.讨论了逗号操作符,.逻辑与操作符&&.逻辑或操作符||和条件操作符?:的问号处需要序列点的原因.举例分析了序列点在表达式求值中的作用. 关键字:序列点 表达式求值 C语言 C语言作为一种主流程序设计语言,许多编程语言如Java.C++.C#都借鉴了它的语法.C语言也是一种很适当的程序设计入门的教学语言,国内大专院校的许多专业都开设了这门课程并且大多将其作为第一门程序设计语言课程,同时C语

【足迹C++primer】表达式求值

表达式求值 /** * 功能:表达式求值(0到9) * 时间:2014年6月15日08:02:31 * 作者:cutter_point */ #include<stdlib.h> #include<stack> #include<iostream> #include<string> using namespace std; stack<int> intStack; //存放数值的栈 stack<char> charStack; //存

C/C++ 语言中的表达式求值

蛱酝缒 C/C++ 语言中的表达式求值

JAVA-栈实现中序表达式求值

中序表达式对我们而言是很直观的(我们平时接触的就是这个),但计算机处理起来比较麻烦(括号.优先级之类的),前序和后序表达式中没有括号,而且在计算中只需单向扫描,不需要考虑运算符的优先级.如2*3/(2-1)+3*(4-1) 前序表达式就是前缀表达式,不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,例如:+/*23-21*3-4,也称为"波兰式". 后序表达式与前序表达式扫描方式正好相反,例如:23*21-/341-*+. 用两个栈实现中序表达式求值,表达式中只支