如何通过编程将数学表达式转换为因子总和?

时间:2019-01-14 12:40:45

标签: c# math mathematical-optimization abstract-syntax-tree

我正在处理一个棘手的旧版计算系统

它是如此挑剔,以至于不能仅仅让它计算a+b*c。相反,您需要将其发送为:

{ a }
{ b, c }

具体来说,在C#中,计算是这样表达的因子之和的列表:

var calculationRequest = new List<string[]> 
{ 
    new [] { "a" },
    new [] { "b", "c" },
};

var result = calculator.Calculate(calculationRequest);

它如何工作?

它的作用是将每一行中的变量相乘,然后将所有行相加。

我遇到的问题是我想创建一种算法来将表达式转换为遗留系统所需的结构。

目前,我已经创建了一个解析器,将每个表达式转换为操作树。

例如a+b*c变成

enter image description here

但是如何将该树转换为遗留系统所需的结构?也就是说,如何将AST转换为因子总和列表?

我完全被困住了。

其他信息

旧版系统可以处理减法和除法运算,并在每个标识符之前添加“-”或“ /”。

例如,a-b会变成

{ a }
{ -b }

a+(b/c)会变成

{ a }
{ b, /c }

1 个答案:

答案 0 :(得分:0)

我找到了使用Math.NET

中的 Math.NET Symbolics 的最简单方法

这样做的关键语法如下:

SymbolicExpression.Parse("a*(b+c)").Expand().Summands().Select(x => x.Factors());

在其中,我展开表达式,然后得到加法运算符。对于每个被加数,我都会知道因素。

为了更好地说明它,请考虑以下表达式:

a * (b + c* -d)

因子总和将使用以下代码返回:

var expression = "a*(b+c*-d)";
var sumsOfFactors = SymbolicExpression.Parse(expression)
    .Expand()
    .Summands()
    .Select(x => x.Factors());

var factorsStr = sumsOfFactors.Select(x => string.Join("\t", x));
var sumOfFactorsStr = string.Join("\n", factorsStr);
Console.WriteLine(sumOfFactorsStr);

打印出因素的总和:

a   b
-1  a   c   d

这正是我想要的。