Last active
September 28, 2021 08:24
-
-
Save AliHadiOzturk/861c7f0b3b80bdd92f8c981818662d8e to your computer and use it in GitHub Desktop.
Convert String to mathematics formulas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
namespace Test.Helpers | |
{ | |
public static class StringToFormula | |
{ | |
private static string[] _operators = { "-", "+", "/", "*", "^" }; | |
private static Func<double, double, double>[] _operations = { | |
(a1, a2) => a1 - a2, | |
(a1, a2) => a1 + a2, | |
(a1, a2) => a1 / a2, | |
(a1, a2) => a1 * a2, | |
(a1, a2) => Math.Pow(a1, a2) | |
}; | |
public static double Eval(string expression) | |
{ | |
List<string> tokens = getTokens(expression); | |
Stack<double> operandStack = new Stack<double>(); | |
Stack<string> operatorStack = new Stack<string>(); | |
int tokenIndex = 0; | |
while (tokenIndex < tokens.Count) | |
{ | |
string token = tokens[tokenIndex]; | |
if (token == "(") | |
{ | |
string subExpr = getSubExpression(tokens, ref tokenIndex); | |
operandStack.Push(Eval(subExpr)); | |
continue; | |
} | |
if (token == ")") | |
{ | |
throw new ArgumentException("Mis-matched parentheses in expression"); | |
} | |
//If this is an operator | |
if (Array.IndexOf(_operators, token) >= 0) | |
{ | |
while (operatorStack.Count > 0 && Array.IndexOf(_operators, token) < Array.IndexOf(_operators, operatorStack.Peek())) | |
{ | |
string op = operatorStack.Pop(); | |
double arg2 = operandStack.Pop(); | |
double arg1 = operandStack.Pop(); | |
operandStack.Push(_operations[Array.IndexOf(_operators, op)](arg1, arg2)); | |
} | |
operatorStack.Push(token); | |
} | |
else | |
{ | |
operandStack.Push(double.Parse(token)); | |
} | |
tokenIndex += 1; | |
} | |
while (operatorStack.Count > 0) | |
{ | |
string op = operatorStack.Pop(); | |
double arg2 = operandStack.Pop(); | |
double arg1 = operandStack.Pop(); | |
operandStack.Push(_operations[Array.IndexOf(_operators, op)](arg1, arg2)); | |
} | |
return operandStack.Pop(); | |
} | |
private static string getSubExpression(List<string> tokens, ref int index) | |
{ | |
StringBuilder subExpr = new StringBuilder(); | |
int parenlevels = 1; | |
index += 1; | |
while (index < tokens.Count && parenlevels > 0) | |
{ | |
string token = tokens[index]; | |
if (tokens[index] == "(") | |
{ | |
parenlevels += 1; | |
} | |
if (tokens[index] == ")") | |
{ | |
parenlevels -= 1; | |
} | |
if (parenlevels > 0) | |
{ | |
subExpr.Append(token); | |
} | |
index += 1; | |
} | |
if (parenlevels > 0) | |
{ | |
throw new ArgumentException("Mis-matched parentheses in expression"); | |
} | |
return subExpr.ToString(); | |
} | |
private static List<string> getTokens(string expression) | |
{ | |
string operators = "()^*/+-"; | |
List<string> tokens = new List<string>(); | |
StringBuilder sb = new StringBuilder(); | |
foreach (char c in expression.Replace(" ", string.Empty)) | |
{ | |
if (operators.IndexOf(c) >= 0) | |
{ | |
if (sb.Length > 0) | |
{ | |
tokens.Add(sb.ToString()); | |
sb.Length = 0; | |
} | |
tokens.Add(c.ToString()); | |
} | |
else | |
{ | |
sb.Append(c); | |
} | |
} | |
if (sb.Length > 0) | |
{ | |
tokens.Add(sb.ToString()); | |
} | |
return tokens; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment