Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以编程方式将字符串转换为数学表达式_C#_Math_Expression_Formula - Fatal编程技术网

C# 如何以编程方式将字符串转换为数学表达式

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

我是C#的初学者。在将字符串转换为数学表达式时,我遇到了一个问题。我有一个用户界面,用户可以使用随机公式字段创建公式。在另一个UI中,用户将输入这些公式字段

例如,第一次公式可能是
(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);