Por acaso nunca tinha precisado de avaliar uma string em C# para calcular o valor numérico dela, e fiquei surpreendido quando me apercebi que o C# não tinha de framework uma função equivalente ao Eval do javascript. Como a minha necessidade era só para contas simples somas, multiplicações, etc resolvi perguntar ao meu amigo Google se ele tinha alguma coisa que me resolvesse o meu problema.
Apesar de não ter encontrado nenhum código facilmente 'digerível' em meia dúzia de minutos e que não fosse uma black-box, encontrei um código que sabia fazer umas continhas, mas só funcionava para números com um dígito e para ter noção de precedência tinham que forçosamente serem colocados parêntesis. Após alterar esse código cheguei ao seguinte resultado:
Apesar de não ter encontrado nenhum código facilmente 'digerível' em meia dúzia de minutos e que não fosse uma black-box, encontrei um código que sabia fazer umas continhas, mas só funcionava para números com um dígito e para ter noção de precedência tinham que forçosamente serem colocados parêntesis. Após alterar esse código cheguei ao seguinte resultado:
public static double Evaluate(String input){
String expr = input.Substring(0, 1) == "(" ? input : "(" + input + ")";
expr = expr.Replace("+", ")+(");
expr = expr.Replace("-", ")-(");
Stack<string> ops = new Stack<string>();
Stack<double> vals = new Stack<double>();
for (int i = 0; i < expr.Length; ++i){
String s = expr.Substring(i, 1);
if (s.Equals("(")) { }
else if (s.Equals("+")) ops.Push(s);
else if (s.Equals("-")) ops.Push(s);
else if (s.Equals("*")) ops.Push(s);
else if (s.Equals("/")) ops.Push(s);
else if (s.Equals(")")){
int count = ops.Count;
while (count > 0){
String op = ops.Pop();
double v = vals.Pop();
if (op.Equals("+")) v = vals.Pop() + v;
else if (op.Equals("-")) v = vals.Pop() - v;
else if (op.Equals("*")) v = vals.Pop() * v;
else if (op.Equals("/")) v = vals.Pop() / v;
vals.Push(v);
count--;
}
}else{
int idx = expr.IndexOfAny(new char[] { '+', '-', '/', '*', ')' }, i);
vals.Push(Double.Parse(expr.Substring(i, idx - i)));
i += (idx - i - 1);
}
}
return vals.Pop();
}
Sem comentários:
Enviar um comentário