Knocks/BackEnd/Knoks.Sandbox/Experiments/StringEvaluation.cs

67 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
namespace Knoks.Sandbox
{
public static class StringEvaluation
{
//StringEvaluation.Eval("(12+22)");
//StringEvaluation.Eval("5*4/2");
//StringEvaluation.Eval("((3+5)-6)");
//StringEvaluation.Eval("pow(3,5)");
//StringEvaluation.Eval("sqrt(4)");
//StringEvaluation.Eval("2.5*2");
//StringEvaluation.Eval("2+3* 3");
//StringEvaluation.Eval("sqrt(sqrt(pow(2,2)))");
public static double Eval(string input)
{
var lambdaParser = new NReco.Linq.LambdaParser();
//var ans = Evaluate(input);
IDictionary<string, object> varContext = new Dictionary<string, object>();
varContext["pow"] = (Func<string, string, double>)((num, power) => Math.Pow(Eval(num), Eval(power)));
varContext["sqrt"] = (Func<string, double>)((num) => Math.Sqrt(Eval(num)));
var ans = lambdaParser.Eval(input, varContext);
Console.WriteLine(input + " = " + ans);
return Convert.ToDouble(ans);
}
public static double Evaluate(string input)
{
string expr = "(" + input + ")";
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("^")) 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;
else if (op.Equals("^")) v = Math.Pow(v, vals.Pop());
vals.Push(v);
count--;
}
}
else vals.Push(double.Parse(s));
}
return vals.Pop();
}
}
}