如何使用文本文件中的公式

本文关键字:文件 何使用 文本 | 更新日期: 2023-09-27 18:28:03

我有一个桌面 c# 应用程序,它使用公式根据用户的输入计算值。

如果有办法从文本文件中获取公式并使用它而不是对其进行硬编码,我会徘徊,这将使在编译程序后轻松更改公式。

问题是将此字符串从文本文件转换为可在代码中使用的公式。

谢谢

如何使用文本文件中的公式

是的,这是一个好主意。但是,如果您从文本文件中获取数据类型,则数据类型将出现问题。您还需要对此进行良好的验证。

根据我的建议,您必须为此使用XML。

它易于处理,您可以选择更准确的数据作为比较文本文件

我想您可能想尝试直接解析公式字符串以计算结果。但是,使用 XML 来存储公式也是一个好主意(尽管您必须自己键入从实际公式转换的公式,但要做到这一点,您必须了解一些用于表示公式的 XML 结构。别担心,这很简单(。首先,我谈谈表达公式的 XML 结构。它有 2 种类型的节点:

  1. 操作数节点:此节点具有名称 operand,具有 1 个名为 value 的属性,并且没有任何子元素。它的value可以是数字或变量(占位符(,以便您可以在运行时传递一些值。例子:

    <operand value="1234"/>
    <operand value="x"/>
    
  2. 运算符节点
  3. :此节点的名称与其支持的运算符相似。为简单起见,我想您的公式仅支持 4 个运算符:+-*/ 。加法用标签<add>表示,减法用标签<sub>表示,乘法用标签<mul>表示,除法用标签<div>表示。每个运算符节点有 2 个元素(因为运算符是二进制的(。每个元素都是一个操作数。这对上面提到的operand节点并不严格,它可以是另一个operator节点。这就是有关 XML 结构的全部知识。例子:

    //expression of (x + y)
    <add>
      <operand value="x"/>
      <operand value="y"/>
    </add>
    

以下 XML 是公式 f(x,y) = (x + y - x/y) * (x-y) / 5 的示例。此公式需要在运行时计算 2 个变量。

<mul>
  <sub>
     <add>
        <operand value="x"/>
        <operand value="y"/>
     </add>
     <div>
        <operand value="x"/>
        <operand value="y"/>
     </div>
  </sub>
  <div>
     <sub>
        <operand value="x"/>
        <operand value="y"/>
     </sub>
     <operand value="5"/>
  </div>
</mul>

这是处理它的代码:

public class ArgumentInfo
{
   public string Name { get; set; }
   public double Value { get; set; }
}
public double ComputeNode(XElement node, params ArgumentInfo[] args)
{
        var operands = node.Elements().ToList();
        if (operands.Count == 0)
        {
            if (node.Name != "operand") throw new ArgumentException("XML formula error! Please check it");
            ArgumentInfo o = args.FirstOrDefault(x => x.Name == node.Attribute("value").Value);
            return o == null ? double.Parse(node.Attribute("value").Value) : o.Value;
        }    
        if (operands.Count != 2) throw new ArgumentException("XML formula error! Please check it");    
        var a = ComputeNode(operands[0], args);
        var b = ComputeNode(operands[1], args);
        if (node.Name == "add") return a + b;
        else if (node.Name == "sub") return a - b;
        else if (node.Name == "mul") return a * b;
        else return a / b;            
}
public double Compute(string xmlFormula, params ArgumentInfo[] args)
{
        XDocument doc = XDocument.Parse(xmlFormula);
        return ComputeNode(doc.Root, args);
}
public double ComputeFormulaFromPath(string xmlFormulaPath, params ArgumentInfo[] args)
{
        XDocument doc = XDocument.Load(xmlFormulaPath);
        return ComputeNode(doc.Root, args);
}
//Example f(x,y) = (x + y - x/y) * (x-y) / 5 with (x,y) = (10,20)
var result = ComputeFormulaFromPath(@"E:'yourFormula.xml", new ArgumentInfo {Name = "x", Value = 10}, 
                                                           new ArgumentInfo {Name="y",Value=20});
//The result is -59

您还可以定义一些名为 <formula> 的标记来表示公式,并且可以在同一xml文件中定义多个公式。

我认为你不能按照你的方法动态使用公式。我并不是说这是不可能的,但让它成为可能会在你的应用程序中需要更多的额外填充物。

举一个更简单的案例

您的文本文件有几个简单的公式,格式如下:

Add : a+b
Simple Interest : (P*R*T)/100
Progression = 1+2+3... n+ (n+1)+(n+2)....

那么,您能否告诉我您将如何选择上面示例中P,R,T,n,a,b的公式的动态部分。

AFAIK,如果您将公式放在代码中,这将很容易。是的,你可以做一件普通的事情。创建一个类文件,该文件将包含程序所需的所有公式作为方法的通用方法,并在需要时调用它们。

见下文

public static class MathematicalBench
{
    public static double SimpleInterest(double principal, double rate, double time)
    {
       return (principal*rate*time)/100;
    }
}

现在在任何需要的地方打电话

Class A:
    private void SomeMethod1()
    {
       // Your logic 
       var interest=  MathematicalBench.SimpleInterest(128765.98,3.6,16);
    }
Another Class B:
    private void SomeNewMethod1()
    {
       // Your logic 
       var interest=  MathematicalBench.SimpleInterest(6523898,6.2,10);
    }

当然,这将更加灵活和容易。