如何以编程方式将数学表达式转换为因子之和?

How to convert a math expression into sums of factors programmatically?

我正在处理一个棘手的遗留计算系统

它太挑剔了,你不能只告诉它计算 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变成

但是如何将这棵树转换成遗留系统需要的结构呢?也就是说,如何将 AST 转换为因子和列表?

我完全卡住了。

附加信息

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

例如,a-b会变成

{ a }
{ -b }

a+(b/c)会变成

{ a }
{ b, /c }

我找到了使用 Math.NET Symbolics 的最短方法 Math.NET

这样做的关键语法是这样的:

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

这正是我要找的。