65.9K
CodeProject 正在变化。 阅读更多。
Home

简单多项式加减法

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2014年12月2日

CPOL

3分钟阅读

viewsIcon

19774

downloadIcon

293

使用 Lambda 表达式对列表进行排序的简单多项式加减法

引言

这个项目展示了一种用 C# 实现多项式加减法的方法。

背景

你可能还记得你的第一节代数课,在 3.14x3 中,3.14 是系数,x 是变量,3 是指数。 这被称为一个,多项式是一个或多个项的和。多项式的加减法非常简单。 例如,要将 4x3 + 3x2 + 5x 和 3x3 - 2x2 + 3x 相加,你需要对齐同类项,然后将系数相加

4x3 + 3x2 + 5x
3x3 - 2x2 + 3x
--------------
7x3 + 1x2 + 8x

当项包含多个变量时,事情会变得棘手,例如,x3y2z4。 由于这在数学上与 z4y2x3 相同,如果我们将多项式表示为 C# 中的 `List`,我们将必须实现某种类型的排序来保持我们所有项的一致性。 这就是 Lambda 表达式有用的地方。 Lambda 表达式是 C# 的一个强大功能,在网络和 CodeProject 上都有大量文档,所以我不会尝试解释它们。 Jon Skeet 就是其中一位,他很好地解释了 Lambda 表达式。

Using the Code

类 `Variable` 存储一个变量,例如 x3,其中 `Name` 是 'x',`Exp` 是 3。 请注意,我们正在使用 C# 的自动实现属性。

public class Variable
{
   public char Name { get; set; }
   public int Exp { get; set; }
}

类 `Term` 用于存储一个项,例如 3.0x2y3,其中 3.0 是系数,`Vars` 是两个变量的泛型列表,一个是 `Name` 是 'x',`Exp` 是 2,另一个是 `Name` 是 'y',`Exp` 是 3。

public class Term
{
    public double Coefficient { get; set; }
    public List<Variable> Vars { get; set; }
}

存储多项式的类 `Poly` 只是一个 Term 的泛型列表

public class Poly
{
    private List<Term> Terms { get; set; }
}

我承认在代码中构造多项式是相当笨拙的,我计划在下一个版本中添加一个解析器来简化这项任务。 然后,这就是我们构建两项多项式 3.5x3y2z4 - 2.7x2y3 的方法

Poly polynomial1 = new Poly();
Term t10 = new Term(+3.5, new List<Variable> 
{ new Variable('x', 3), new Variable('y', 2), new Variable('z', 4) });
Term t11 = new Term(-2.7, new List<Variable> 
{ new Variable('x', 2), new Variable('y', 3) });
polynomial1.AddTerm(t10);
polynomial1.AddTerm(t11);
Console.WriteLine("{0}", polynomial1.ToString());

请注意,`ToString()` 被重载并像这样显示多项式

+  3.50x^3y^2z^4 -  2.70x^2y^3

当两个多项式具有相同的项时,系数会如前所述相加。 这是通过在 `public Poly Sum(Poly addend)` 方法中,遍历多项式的每一项并添加系数来完成的。(在这个版本中,我将列表转换为数组以简化这项任务。)但是,假设我们希望添加两个多项式,它们的项(暂时忽略系数)在数学上是相同的,但是变量的顺序不同,例如 10.0x3y2z4 和 20.0z4y2x3。 我选择的策略是使用 `AddTerm()` 方法中的这个 Lambda 表达式按字母顺序对变量进行排序

term2.Vars.Sort((t1, t2) => t1.Name.CompareTo(t2.Name));

现在,多项式的变量将按相同的顺序排列:10.0x3y2z4 和 20.0z3y2z4。 同样在 `AddTerm()` 中,我构建了一个名为 `sortString` 的 `string`,它只包含变量和指数,没有系数,以便轻松比较两个项以查看它们是否可以相加。 在此示例中,`sortString` 为“x3y2z4”。 当我们添加两个多项式时,当我们遍历项列表时,如果 `sortString` 相同,则意味着我们添加系数。 由于习惯上将具有第一个变量最高系数的项写在最前面,因此我使用这个 Lambda 表达式对所有项进行排序

Terms.Sort((t1, t2) => t2.SortString.CompareTo(t1.SortString));

`Poly` 类中的 `Sum()` 方法假定两个多项式具有相同的项,并且仅系数不同。 问题是当一个多项式中存在一个项,但另一个多项式中缺少该项时该怎么办。 我选择的策略是将缺少的项添加到缺少它的多项式中,系数为零(我称之为“虚拟”项)。 这是在 `Poly` 类中的方法 `Normalize(Poly p1, Poly p2)` 中实现的。

关注点

`Term` 类实现了 `IEquatable` 接口。 `Equals` 方法比较 `sortString` 以确定两个项是否等效。 我在源代码中包含了描述此接口的链接。

历史

  • 2014 年 11 月 30 日:版本 1
© . All rights reserved.