用于评估数学表达式的最佳算法? [英] Best algorithm for evaluating a mathematical expression?

查看:120
本文介绍了用于评估数学表达式的最佳算法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

评估数学表达式的最佳算法是什么?我想能够优化这一点,因为我可能有一个公式与各种变量,我可能需要评估数百次使用不同的变量。所以基本上,如果我可以初始解析公式,以便以某种方式进行优化,然后我可以将变量传递给这个优化版本,因为我需要多次,每次为我生成一个结果。

What's the best algorithm for evaluating a mathematical expression? I'd like to be able to optimize this a little in the sense that I may have one formula with various variables, which I may need to evaluate hundreds of times using different variables. So basically if I can initially parse the formula so that it is optimized in some way, and I can then pass in the variables to this optimized version as many times as I need, each time it produces a result for me.

我将在Delphi或C#中编写。我已经通过使用分流场算法编写了类似的东西,但是每当我需要计算相同的公式时,我必须经过解析阶段。必须有一个更好的方式来做到这一点。

I'll be writing this in either Delphi or C#. I have already written something similar by using the shunting yard algorithm, but each time I need to calculate the same formula, I'm having to go through the parsing stage. There must be a better way to do this.

推荐答案

如果要使用Delphi进行操作,可以查看 JclExprEval 单元作品,是 JEDI代码库的一部分。几年前我写了(这有点过度设计);它解析函数和变量,并且可以回传一个快速评估表达式的方法指针。通过引用传递变量,您可以直接更改它们,并相应地计算重新计算的表达式。

If you want to do it with Delp you could look into how the JclExprEval unit works, part of the JEDI Code Library. I wrote it several years ago (it's a little over-engineered); it parses functions and variables and can hand you back a method pointer which evaluates the expression quickly. Pass the variables in by reference, and you can change them directly and the re-evaluated expression will be calculated accordingly.

无论如何,它的基本原理如何对你有帮助表达式的递归下降解析很容易,通过构建树可以多次评估,无需重新解析。 JclExprEval实际上为一个简单的堆栈机器生成代码,因此它可以比树解释更快一些;堆栈机器很大程度上将其内存操作限制为阵列,并使用开关作为操作码,而树解释则遵循整个堆中的链接,并且经常使用虚拟调度(或双调度)作为操作码,因此通常会更慢。

In any case, the basics of how it works may be helpful for you. Recursive-descent parsing of expressions is easy, and by building a tree you can evaluate multiple times without re-parsing. JclExprEval actually generates code for a simple stack machine, so that it can work a little faster than tree interpretation; stack machines largely restrict their memory operations to arrays and use switches for opcodes, while tree interpretation follows links throughout the heap and often uses virtual dispatch (or double-dispatch) for opcodes, so they usually end up slower.

采用与code> JclExprEval 相同的方法,但在C#中编写,并构建一个 Expression 是另一个完全有效的方法。 JIT编译的表达式应该比解释表达式程序或树更快一些,它们本身比解析快很多。

Taking the same approach as JclExprEval in parsing but written in C#, and building up an Expression, like Marc suggests, is another perfectly valid approach. The JIT-compiled expression ought to be quite a bit faster than an interpreted expression program or tree, which themselves are a lot faster than parsing.

这篇关于用于评估数学表达式的最佳算法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆