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

标签 c# math expression formula

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

例如,第一次公式可能是 (a+b)^n 而另一个公式可能是 ((a+b+c)^n+b).

在我的计算 UI 中,用户第一次输入 a、b、n,而对于第二个公式,用户输入 a、b、c、n。任何人都可以帮助我如何以编程方式获得两个公式的结果吗?提前致谢

最佳答案

应该这样做:

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;
    }
}

像这样调用类和方法:

string formula = "type your formula here"; //or get it from DB
StringToFormula stf = new StringToFormula();
double result = stf.Eval(formula);

关于c# - 如何以编程方式将字符串转换为数学表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21750824/

相关文章:

python - 了解因式分解函数

c - 归一化最小均方 - C 实现

c# - Entity Framework 结合来自不同实体的 lambda 表达式

awk - 用于交换列的 SED 表达式

c# - LuaInterface - 如何限制对 .Net 类的访问?

c# - 通过评论禁用所有 Resharper 警告

math - 用 Python 数到一百万 - 理论

R 基本图形 : Annotate with logical symbols (and/or)

c# - 如何在 ASP.NET Core RC2 中制作 websocket 服务器?

c# - TextBox 允许输入文本但不显示插入符号