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

时间:2013-08-18 22:39:36

标签: c# winforms text-files formula type-conversion

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

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

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

谢谢

3 个答案:

答案 0 :(得分:1)

是的,这是一个好主意。但是如果从文本文件中获取数据类型,数据类型将会出现问题。你还需要很好的验证。

根据我的建议,你必须使用XML。

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

答案 1 :(得分:1)

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

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

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

    //expression of (x + y)
    <add>
      <operand value="x"/>
      <operand value="y"/>
    </add>
    
  3. 以下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文件中定义许多公式。

答案 2 :(得分:0)

我不认为你可以根据你的方法动态使用公式。我并不是说这是不可能的,但是可以在你的应用程序中使用更多的东西。

采取更简单的案例

您的文本文件包含以下格式的简单公式:

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);
    }

当然,这会更灵活,更容易。