0

我正在用 C# 编写一个程序,该程序从用户输入中获取一个方程并对其进行评估。目前,我有一种方法可以计算用户输入并从存储的变量(例如 x)中获取值。将输入的方程式将类似于2.0 * 78 * 4X / 3

目前我可以用X与之关联的值替换。但是我需要一种搜索​​字符串并找到的方法X,然后如果X在它之前有一个数字,则乘以X * X该次数。在上面的示例中,这将是 4 次。

最好使用该IndexOf方法还是将字符串拆分为子字符串?

我想要的只是能够找到X前面有一个数字的天气;如果不是,则只输出 的值X,否则如果在乘以所述倍X之前有一个数字。X*X

这是我用于查找X传递的数据的代码。理想情况下,我想包含以下任何代码:

if (name == "x" || name == "X")
{
    args.Result = x; // Returns value of x
}

这是所有其余的代码

var e = new Expression(input);

// Set up a custom delegate so NCalc will ask you for a parameter's value
// when it first comes across a variable
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
    if (name == "x" || name == "X")
    {
        args.Result = x; // Returns value of x
    }
    else if (name == "y" || name == "Y")
    {
        //....
    }
    else if (name == "z" || name == "Z")
    {
        //....
    }

    // Or if the names match up you might be able to something like:
    //  args.Result = dataRow[name];
};

//var result =  
return e.Evaluate();
4

2 回答 2

0

你可以用正则表达式来做到这一点。一个简单的例子:

class MainClass
{
    private static int X = 3, Z = 5, Y = 10;

    public static void Main (string[] args)
    {
        string eqn = "2.5Y * 78Z * 4X / 3 + H * 3N";

        string regex = "(?<var>[a-z])|(?<int>(\\d+(\\.\\d+))|(\\d+))(?<var>[a-z])";

        Regex r = new Regex (regex, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
        MatchCollection m = r.Matches (eqn);
        if (m.Count > 0) 
        {
            foreach (Match ma in m) {
                MatchVar (ma);
            }
        }
    }

    private static void MatchVar (Match m)
    {
        string stringValue = string.IsNullOrEmpty (m.Groups ["int"].ToString ()) ? "1" : m.Groups ["int"].ToString ();
        double value = double.Parse (stringValue);
        string var = m.Groups ["var"].ToString ();
        switch (m.Groups ["var"].ToString ()) 
        {
            case "X":
                Console.WriteLine ("Result for {0}: {1}", var, value * X);
                break;
            case "Z":
                Console.WriteLine ("Result for {0}: {1}", var, value * Z);
                break;
            case "Y":
                Console.WriteLine ("Result for {0}: {1}", var, value * Y);
                break;
            default: 
                Console.WriteLine ("No value defined for {0}", var);    
                break;
        }
    }
}
于 2013-03-24T20:08:22.853 回答
0

我认为你应该制作一个“真正的”解析器,它会创建一个表达式树。

您可以手动执行此操作,请参阅例如 http://www.codeproject.com/Articles/88435/Simple-Guide-to-Mathematical-Expression-Parsing

或者您可以使用现成的解析器生成器,例如 ANTLR,您可以提供简单的语法,请参见 http://www.codeproject.com/Articles/18880/State-of-the-Art-Expression-Evaluation

无论哪种方式,对于变量值,您可能应该将它们保存在Dictionary<string, double>

public double GetVariableValue(string varName)
{
    double val;
    if (!variables.TryGetValue(varName, out val))
       throw new InvalidOperationException("Undefined variable "+varName);
    return val;
}
于 2013-03-24T18:51:36.117 回答