1
\$\begingroup\$

I have a string like str = " 4+ 6 * 30";. I have to perform an arithmetic operation on this using C#; My solution to this problem is as follows.

     string temp = " 4 + 6 * 5";
     int firstNaum = 0;
     int secondNum = 0;
     int ThirdNum = 0;
     int finalResults = 0;
    //Spliting strings
    string[] withoutOperator = temp.Split('\t',' ','*' , '+');
    //Iterating strings 
    int counter = 0;
    foreach (var res in withoutOperator)
    {
        if (!string.IsNullOrEmpty(res) && counter ==1)
        {
            firstNaum = Convert.ToInt32(res);
        }
        if (!string.IsNullOrEmpty(res) && counter== 4)
        {
            secondNum = Convert.ToInt32(res);
        }
        if (!string.IsNullOrEmpty(res) && counter == 7)
        {
            ThirdNum = Convert.ToInt32(res);
        }
        counter += 1;
    }
    finalResults = firstNaum + secondNum * ThirdNum;
\$\endgroup\$
1
  • 8
    \$\begingroup\$ The process that you're using is very tightly coupled to your example, and not at all extensible to other input strings. \$\endgroup\$
    – krillgar
    Jul 24, 2014 at 16:17

4 Answers 4

16
\$\begingroup\$

One of the simplest and easiest ways to evaluate math expressions is to use the Compute method of the DataTable class:

DataTable dt = new DataTable();
int answer = (int)dt.Compute("2+(4*3)*4", "");

answer is 50.

One caveat you'll have to trap exceptions to catch invalid expressions.

\$\endgroup\$
10
\$\begingroup\$

Your solution is very limited. As it only take a string in in the following format x1 x2 x3, and apply to the function x1+x2*x3.

To build an expressional calculator, you need to go through these steps :

  1. Segmentate the expression into a list of tokens
  2. Parse the tokens into recognizable lexemes(numbers, operator, parenthesis, etc)
  3. Transform the list into a tree structure based on the order of operations
  4. Calculate the result of top root, which requires the results from its branch(es)
\$\endgroup\$
1
  • 3
    \$\begingroup\$ However, such expressions are extremely easy to parse and calculate, as the Shunting-Yard algorithm can be used to evaluate the tokens. So of your four steps, only two remain: tokenization (I don't get why you split that into two phases), and evaluation via Shunting-Yard. \$\endgroup\$
    – amon
    Jul 24, 2014 at 16:41
6
\$\begingroup\$

Can you clarify what you want us to feed back on.

My thoughts are:

  1. Use a library that already performs infix mathematical parsing because the process is relatively complex but has been "solved" many times before.
  2. Your code assumes a very strict order in the the operations. That doesn't make it very extensible.
  3. Try adding validation. instead of Convert.ToInt32(res), use int.TryParse(res, out n). if the function returns false, you know the parse failed and you can handle it as you feel fit.
  4. Maybe Trim() your res on each loop - although you will need to assign it to a new variable (e.g. var res2 = res.Trim();)
\$\endgroup\$
3
\$\begingroup\$

I believe Jace.net is what you're looking for. Here is the official Github link.

Here is a basic evaluation from a string expression:

CalculationEngine engine = new CalculationEngine();

Dictionary<string, double> variables = new Dictionary<string, double>();
variables.Add("var1", 2);

double result = engine.Calculate("5 % (2 + var1)", variables );

And here is an example calculating a math expression which has a log operator:

Dictionary<string, double> variables = new Dictionary<string, double>();
variables.Add("var1", 2.5);
variables.Add("var2", 3.4);

CalculationEngine engine = new CalculationEngine();
double result = engine.Calculate("logn(var1, var2)", variables);
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.