0

I am making a program in C# that takes an equation from the user input and evaluates it. At the moment I have a way of it calculating the user input and also taking values from stored variables such as x. The equation the will enter will be something like 2.0 * 78 * 4X / 3.

At the moment I can replace X with the value associated with it. However I need a way of searching the string and finding X, then if X has a number before it, multiplying X * X that number of times. In the example above, that would be 4 times.

Would it be best to use the IndexOf method or split the string into sub strings?

All I want is to be able to find weather X has a number before it; if not then just output the value of X, else if X has a number before it multiply X*X said times.

This is the code I have for finding X to the data passed,. Ideally I would like to contain any code withing the following:

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

This is all rest of the code

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();
joce
  • 9,624
  • 19
  • 56
  • 74
Colm Clarke
  • 480
  • 1
  • 7
  • 23

2 Answers2

0

I think you should make a "real" parser, that creates an expression tree.

You can either do this manually, see e.g. http://www.codeproject.com/Articles/88435/Simple-Guide-to-Mathematical-Expression-Parsing

Or you can use an off-the-shelf parser generator such as ANTLR that you feed a simple grammar, see e.g. http://www.codeproject.com/Articles/18880/State-of-the-Art-Expression-Evaluation

Either way, for the variable values you should probably just keep them in a Dictionary<string, double>

public double GetVariableValue(string varName)
{
    double val;
    if (!variables.TryGetValue(varName, out val))
       throw new InvalidOperationException("Undefined variable "+varName);
    return val;
}
Anders Forsgren
  • 10,827
  • 4
  • 40
  • 77
0

You could do this with RegEx. A simple example:

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;
        }
    }
}
Nathan Marlor
  • 176
  • 1
  • 8