简体   繁体   English

如何确定数学表达式的求值顺序?

[英]How to determine the order of evaluation of a mathematical expression?

Given a mathematical expression, I would like to find out which are the parts that can be evaluated simultaneously. 给定一个数学表达式,我想找出可以同时评估的部分。 For example, given the following expression, 例如,给定以下表达式,

(a + b) * c - (d + e) / f

(a + b) and (d + e) could be evaluated simultaneously because they are independent of each other. (a + b)(d + e)可以同时评估,因为它们彼此独立。

Is there any algorithm for this purpose? 是否有用于此目的的算法? Or is there even any library that implements this functionality? 还是甚至没有实现此功能的库?

This is a short and simple step by step manual for creating math parser. 是创建数学解析器的简短而逐步的手册。 After you have parsed the expression, and you hold a tree representing parsed expression, you can iterate over it, and in every iteration each pairs leaves of the tree will represent an independent expression (that can be evaluated simultaneously). 在解析了表达式之后,您拿着一棵表示已解析表达式的树,可以对其进行迭代,并且在每次迭代中,树的每对叶子将代表一个独立的表达式(可以同时求值)。 [in every iteration replace the evaluated expressions with their result] [在每次迭代中,将计算出的表达式替换为其结果]

Building Expression Evaluator with Expression Trees in C# 在C#中使用表达式树构建表达式评估器

在此输入图像描述

The order of evaluation depends on two factor : 评估顺序取决于两个因素:

  • Precedence : in each language usually there is a table that indicate the precedence of each operator 优先级 :每种语言中通常都有一个表,用于指示每种运算符的优先级
  • Associativity : when an expression involves several operators that have the same precedence, the operator associativity governs the order in which the operations are performed. 关联性 :当一个表达式包含多个具有相同优先级的运算符时,运算符的关联性决定操作的执行顺序。

If there could be some optimization that involve simultaneous evaluation of parts of an expression, i think could be done only at JVM/CLR level and not with a library ... 如果可能存在涉及对表达式的各个部分同时求值的某些优化,我认为只能在JVM / CLR级别而不是在库中完成...

I believe you should use the Reversed Polish Notation . 我相信您应该使用波兰语反转符号
Read the following for more details: 阅读以下内容了解更多详情:

This is a function written in C++ that converts normal notation to reversed polish notation. 这是用C ++编写的函数,可将常规表示法转换为反向波兰语表示法。 someone might help you in converting it to C#: 有人可能会帮助您将其转换为C#:

Ok so let's see the example as a tree: 好的,让我们将示例视为一棵树:

          -
   (*           /)
(c    +)     (+    f)
   (a   b) (d   e)

(brackets pair the nodes that are both children of the same parent) (方括号将同一个父节点的两个节点配对)

Getting that tree if simple, for example with the Shunting Yard algorithm. 如果很简单,例如使用Shunting Yard算法获取该树。

Now observe that what you need in order to evaluate a node, are only the children of that node (but recursively so). 现在观察到,评估一个节点所需的只是该节点的子节点(但递归地如此)。 Therefore (a + b) and (d + e) do not depend on each other, as you note. 因此,如您所述, (a + b)(d + e)彼此不依赖。 Also (c * (a + b)) does not depend on (d + e) or on ((d + e) / f) , and ((d + e) / f) does not depend on (a + b) . 同样(c * (a + b))不依赖于(d + e)((d + e) / f) ,并且((d + e) / f)不依赖于(a + b)

In general, taking a node n , any node that's neither a descendant of n not a ancestor, can be evaluated simultaneously. 通常,采用节点n ,它既不是n的后代,也不是祖先的任何节点都可以同时求值。 If you're working with a schedule, you'd have to add "if that node can be evaluated now" - clearly you can not evaluate a node before you've evaluated its descendants. 如果您正在使用计划,则必须添加“如果现在可以评估该节点”-显然,您无法在评估其后代之前评估一个节点。

I'm not sure what "this purpose" is what you refer to. 我不确定您指的是什么“目的”。 What do you want to calculate? 您要计算什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM