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