C# 如何以编程方式将字符串转换为数学表达式
我是C#的初学者。在将字符串转换为数学表达式时,我遇到了一个问题。我有一个用户界面,用户可以使用随机公式字段创建公式。在另一个UI中,用户将输入这些公式字段 例如,第一次公式可能是C# 如何以编程方式将字符串转换为数学表达式,c#,math,expression,formula,C#,Math,Expression,Formula,我是C#的初学者。在将字符串转换为数学表达式时,我遇到了一个问题。我有一个用户界面,用户可以使用随机公式字段创建公式。在另一个UI中,用户将输入这些公式字段 例如,第一次公式可能是(a+b)^n,另一次公式可能是((a+b+c)^n+b) 在我的计算界面中,第一次用户将输入a、b、n,第二次公式用户将输入a、b、c、n。有谁能帮我知道如何得到这两个公式的结果吗?提前感谢公式评估方法很多, 只需将您输入的字符串中的a,b,n字符替换为用户提供的值,并使用上述方法之一解析方程即可。string in
(a+b)^n
,另一次公式可能是((a+b+c)^n+b)
在我的计算界面中,第一次用户将输入a、b、n,第二次公式用户将输入a、b、c、n。有谁能帮我知道如何得到这两个公式的结果吗?提前感谢公式评估方法很多, 只需将您输入的字符串中的
a
,b
,n
字符替换为用户提供的值,并使用上述方法之一解析方程即可。string input=“(12+4*6)*((2+3*(4+2))(5+12));
string input= "(12 + 4 * 6) * ((2 + 3 * ( 4 + 2 ) ) ( 5 + 12 ))";
string str4 = "(" + input`enter code here`.Replace(" ", "") + ")";
str4 = str4.Replace(")(", ")*(");
while (str4.Contains('('))
{
string sub1 = str4.Substring(str4.LastIndexOf("(") + 1);
string sub = sub1.Substring(0, sub1.IndexOf(")"));
string sub2 = sub;
string str21 = sub2.Replace("^", "~^~").Replace("/", "~/~").Replace("*", "~*~").Replace("+", "~+~").Replace("-", "~-~");
List<string> str31 = str21.Split('~').ToList();
while (str31.Count > 1)
{
while (str31.Contains("*"))
{
for (int i = 0; i < str31.Count; i++)
{
if (str31[i] == "*")
{
val = Convert.ToDouble(str31[i - 1]) * Convert.ToDouble(str31[i + 1]);
str31.RemoveRange(i - 1, 3);
str31.Insert(i - 1, val.ToString());
}
}
}
while (str31.Contains("/"))
{
for (int i = 0; i < str31.Count; i++)
{
if (str31[i] == "/")
{
val = Convert.ToDouble(str31[i - 1]) / Convert.ToDouble(str31[i + 1]);
str31.RemoveRange(i - 1, 3);
str31.Insert(i - 1, val.ToString());
}
}
}
while (str31.Contains("+"))
{
for (int i = 0; i < str31.Count; i++)
{
if (str31[i] == "+")
{
val = Convert.ToDouble(str31[i - 1]) + Convert.ToDouble(str31[i + 1]);
str31.RemoveRange(i - 1, 3);
str31.Insert(i - 1, val.ToString());
}
}
}
while (str31.Contains("-"))
{
for (int i = 0; i < str31.Count; i++)
{
if (str31[i] == "-")
{
val = Convert.ToDouble(str31[i - 1]) - Convert.ToDouble(str31[i + 1]);
str31.RemoveRange(i - 1, 3);
str31.Insert(i - 1, val.ToString());
}
}
}
}
str4 = str4.Replace("(" + sub + ")", str31[0].ToString());
}
string sum = str4;
字符串str4=“(“+input`在此处输入代码”.替换(“,”)+”);
str4=str4。替换(“)(“,”*(”);
while(str4.Contains('('))
{
string sub1=str4.Substring(str4.LastIndexOf(“(”)+1);
string sub=sub1.Substring(0,sub1.IndexOf(“)”);
字符串sub2=sub;
字符串str21=sub2.替换(“^”、“~^~”).替换(“/”、“~/~”).替换(“*”、“~*~”).替换(“+”、“~+~”).替换(“-”、“~-~”);
List str31=str21.Split(“~”).ToList();
而(str31.Count>1)
{
while(str31.Contains(“*”)
{
for(int i=0;i
我想到的最结构化的方法是定义由运算符符号组成的语法(在您的例子中,这些符号显然是+、-、*、/和^)和操作数;然后,如果定义语法中存在输入的派生,则派生基本上是表达式树,然后可以递归遍历表达式树,同时将运算符直接转换为实际操作。我承认描述有点模糊,但良好的解析可能有点困难。也许可以看看帮一点忙。我想这就是解决办法
Expression e = new Expression("((a+b+c)^n+b)");
e.Evaluate();
应该这样做:
public class StringToFormula
{
private string[] _operators = { "-", "+", "/", "*","^"};
private 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 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 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 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);
} else {
sb.Append(c);
}
}
if ((sb.Length > 0)) {
tokens.Add(sb.ToString());
}
return tokens;
}
}
什么是
random formula field
和另一个UI
?将其转换为ExpressionTree
我的意思是用户可以使用随机变量随机创建一个公式。@Tarechow转换为expression tree?尝试逃逸,例如,提供了一个简单的示例:这是一种简单的解析器。您可以进一步增强它。下面是一些相关的links…它适用于包含加法、减法、乘法和除法的表达式,如果安装了ncalc Nuget软件包,您可以对其进行更多的增强…是的,它可以工作
string formula = "type your formula here"; //or get it from DB
StringToFormula stf = new StringToFormula();
double result = stf.Eval(formula);