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

创建一个带代数函数的数学库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (9投票s)

2010年10月18日

CPOL

3分钟阅读

viewsIcon

29930

创建带代数函数的数学库的思路

引言

在空闲时间,我一直想知道创建一个 Math 库需要什么;特别是对于代数 - 只是为了好玩。 在尝试了一些想法之后,我想出了一个使用正则表达式的解决方案。 本文现在将讨论开始创建代数库背后的基本概念。 请注意,这远非一个完整的解决方案,而只是一个指针(请原谅这个双关语),如果你想使用 .NET 创建一个 Algebra 库,可以朝哪个方向前进。

单项式、多项式和变量

我们应该做的第一件事是创建一些 struct 来表示变量、单项式和多项式。 这就是我想出的

public struct Variable
{
   public string Name { get; set; }
   public int Exponent { get; set; }

   public Variable(string name, int exponent)
      : this()
   {
      Name = name;
      Exponent = exponent;
   }

   public static Variable Parse(string item){}
   public static bool operator ==(Variable lhs, Variable rhs){}
   public static bool operator !=(Variable lhs, Variable rhs){}
   public static Variable Empty{}
   public override string ToString(){}

public class VariableCollection : List<Variable>
{
   public bool ContainsVariableName(string name){}
   public bool Equals(VariableCollection v2){}
   public override string ToString(){}
}

这是基本组件,一个 Variable 类。 "Name" 属性是变量名 "x" 或 "y" 等。 指数字面上就是那个。 您可以看到有一些运算符重载来检查两个变量是否相等。 这在尝试确定两个变量是否可以加在一起或者它们是否不兼容时会派上用场。

public struct Monomial
{
   public double Coefficient { get; set; }
   public VariableCollection Variables { get; set; }
   public int Exponent { get; set; }

   public static Monomial Parse(string item){}

   public static string operator +(Monomial addend1, Monomial addend2){}
   public static string operator -(Monomial minuend, Monomial subtrahend){}
   public static string operator *(Monomial factor1, Monomial factor2){}
   public static string operator /(Monomial dividend, Monomial divisor){}

   public static string Add(Monomial addend1, Monomial addend2){}
   public static string Subtract(Monomial minuend, Monomial subtrahend){}
   public static string Multiply(Monomial factor1, Monomial factor2){}
   public static string Divide(Monomial dividend, Monomial divisor)[]

   public override string ToString(){}
}

上面的 Monomial 类由系数、变量集合及其自身的指数组成。 例如 (x^4yz^13)^2 可以是一个单项式,其中 xyz 是具有自己指数(分别为 413)的变量,指数 2 适用于整个单项式。 这是主要类,所有繁重的工作都在这里完成。 在这里,我们有用于将单项式相加、相减、相乘和相除的运算符重载。 注意:由于我找不到插入上标的方法,我将使用字符 '^' 来表示指数(幂)。

public struct Polynomial
{
   public IEnumerable<Monomial> Monomials { get; set; }
   public static Polynomial Parse(string item){}
}

正如人们所期望的那样,这一个实际上只是单项式的集合。

注意:有关上述方法的实现,请参见实际代码 (http://algebralib.codeplex.com/)。 在这里,我只是为了清楚起见提供签名。

正则表达式模式

接下来,我们需要指定一些正则表达式模式来匹配用户的输入字符串

internal static Regex IntegerPattern = 
	new Regex(@"(\+|-)?[1-9]+", RegexOptions.Compiled);
internal static Regex VariablePattern = 
	new Regex(@"[a-zA-Z]+", RegexOptions.Compiled);
internal static Regex CoefficientPattern = 
	new Regex(@"(?<value>(?<sign>((\+|-)?))\b(?<coef>([0-9](\.)?)+))[a-zA-Z]", 
	RegexOptions.Compiled);
internal static Regex VariableWithExponentPattern = 
	new Regex(@"([a-zA-Z]+-?(([1-9])*)?)(?![a-zA-z])*", RegexOptions.Compiled);
internal static Regex MonomialPattern = 
	new Regex(@"(([1-9]*)?([a-zA-Z])+-?([1-9]*)?)+", RegexOptions.Compiled);

这些模式用于解析用户的输入。 例如,MonomialPattern 模式将匹配一个单项式。 IntegerPattern 模式将匹配一个整数(忽略其他任何内容),依此类推。

Using the Code

现在我们可以解析单项式并拥有添加、减去、相乘或相除它们的方法,我们需要某种方式将它很好地显示给用户。 请参见下面的屏幕截图

Capture.PNG

此计算由以下事件处理程序生成

private void btnCalculate_Click(object sender, EventArgs e)
{
   // Here we parse the user's input from text boxes 1 & 2
   Monomial m1 = Monomial.Parse(txtValue1.Text.Trim());
   Monomial m2 = Monomial.Parse(txtValue2.Text.Trim());

   // The we check for the selected operation and perform it
   switch (cmbOperation.Text)
   {
      case "+": subSupLbl.Text = m1 + m2; break;
      case "-": subSupLbl.Text = m1 - m2; break;
      case "*": subSupLbl.Text = m1 * m2; break;
      case "÷": subSupLbl.Text = m1 / m2; break;
      default: break;
   }
}

为了向用户正确显示上标,我使用了这里的下标-上标标签。

注意:在我撰写本文时,似乎上述站点现已关闭。 不确定它是否会回来,但非常感谢他编写此控件并为我节省了时间!

结论

还有很多工作要做。 例如,可以将变量作为指数,在这种情况下,任何实际应用程序都不会将 Exponent 属性设置为 int

如果适合你的喜好,请随时进一步研究; 我很想看看它能走多远。 :)

历史

  • 2010 年 10 月 18 日:初始帖子
© . All rights reserved.