Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formula and math expression parser algorithm

Tags:

c#

algorithm

math

I must write a program that able to parsing formula. It should work like this example below :

Input : 5x + 7 ^ sin(z) / 2T + 44
Output : Enter value for x , z , t
Input : 2 , 1 ,2
Output : the answer is : something


It should support (+ , * , - , ^ , % , SIN , COS)
I did read this page about Shunting-yard algorithm

And also I know how to convert Infix expression to postfix or prefix.
It is my algorithm :

1 - Give the expression.
2 - If parentheses are balance go to step 3 else show error go to step 1
3 - Find all variables apart from (SIN , COS)
4 - Give variables from input
5 - Replace variables
6 - Prefix the expression and calculate it
7 - Display result in output and close program

Is that right ? I want to implement it in C#
Please suggest me any note might be useful for me.

like image 929
Shahin Avatar asked Dec 21 '22 15:12

Shahin


1 Answers

If you decide to write this from scratch, your algorithm looks good. I'll provide a few of my thoughts.

You may want to move step 5 (replace variables) into step 6 (prefix the expression and calculate it). In other words, instead of just doing a textual find-and-replace for the variables, do it during the calculation whenever need to evaluate a variable. This could open up more possibilities later, possibly making it easier to graph your functions or have variables with values that depend on other variables. Your way should work for the simple case, though.

A possible implementation for the sin and cos functions, making it easier to define additional functions in the future, could be having a Dictionary<string, Func<double,double>>, something like:

private var functions = 
    new Dictionary<string, Func<double,double>>(StringComparer.OrdinalIgnoreCase)
    {
        { "sin", Math.Sin },
        { "cos", Math.Cos },
        { "sec", Secant }
    };

. . . 

// checking whether a token is a defined function or a variable
if (functions.ContainsKey(token))
{
    // determine the value of the argument to the function
    double inputValue = getArgument();
    double result = functions[token](inputValue);
    . . .
}

. . .

private static double Secant(double x)
{
    return 1.0 / Math.Cos(x);
}
like image 82
Justin Avatar answered Jan 02 '23 00:01

Justin