首页 > 解决方案 > 从字符串 C# Unity3D 解析用户的数学运算

问题描述

我的问题是下一个,我正在尝试制作一种从字符串解析的数学运算的方法,例如字符串操作 =“20-2/2”,结果 = 19

目标是做一个用户可以编写数学表达式来计算统计修饰符(桌面游戏中使用的统计)的字段

这是我能够制作的代码(对不起西班牙名字,我来自拉美)

public int id = 0;

public int Stat = 20;

public bool ejecutarComprobacion = false;

public string textoStatString;
//public string textoMultiStringCalculation = "(Stat - 10) / 2";
public string textoMultiStringCalculation = "s - 10 / 2";
public int resultado;
public string textoMultiString;
public string textoValueString;

public TMP_InputField textoStatImput;
public TMP_Text textoMulti;
public TMP_Text textoValue;

public GameObject panelValue;

public bool tieneMulti = true;
public bool multiArriba = true;

void Update()
{
    if (ejecutarComprobacion) {
        parseMathOperation();
        ejecutarComprobacion = false;
    }   
}

public void parseMathOperation() {

    string operadoresPermitidos = "-+/*";
    string numeros = "0123456789";

    //reseteo el resultado
    resultado = 0;

    //en esta variable guardo el numero capturado
    int numeroCapturado = 0;

    //estas son para capturar operaciones y numeros
    char operacionCapturada = ' ';
    string numeroCompleto = "";

    //estas son para capturar los estados de las operaciones (si es negativo, si es mas largo el nui)
    bool negativo = false;
    bool operacion = false;
    bool Comprobado = false;

    //Debug.Log("Operacion : " + textoMultiStringCalculation);

    for (int i = 0; i < textoMultiStringCalculation.Length; i++)
    {
        if (numeros.IndexOf(textoMultiStringCalculation[i]) != -1) {
            //Debug.Log(textoMultiStringCalculation[i] + " es Numero");
            Comprobado = false;

            numeroCompleto = "";

            while (Comprobado == false) {

                numeroCompleto += textoMultiStringCalculation[i];

                if (i + 1 >= textoMultiStringCalculation.Length)
                {
                    //Debug.Log("numero : " + numeroCompleto);
                    Comprobado = true;
                }
                else {

                    if (numeros.IndexOf(textoMultiStringCalculation[i + 1]) != -1)
                    {
                        i++;
                        Comprobado = false;
                    }
                    else
                    {
                        //Debug.Log("numero : " + numeroCompleto);
                        Comprobado = true;
                    }
                }
            }

            if (operacion == false)
            {

                if (negativo == true)
                {
                    int.TryParse("-" + numeroCompleto, out numeroCapturado);
                    resultado += numeroCapturado;
                    negativo = false;
                }
                else
                {
                    int.TryParse(numeroCompleto, out numeroCapturado);
                    resultado += numeroCapturado;
                }
            }
            else
            {
                int.TryParse(numeroCompleto, out numeroCapturado);
                resultado = operar(resultado, operacionCapturada, numeroCapturado);
            }

        }
        else if (operadoresPermitidos.IndexOf(textoMultiStringCalculation[i]) != -1)
        {
            //Debug.Log(textoMultiStringCalculation[i] + " es operador");
            if (resultado == 0)
            {
                negativo = true;
            }
            else {
                operacion = true;
                operacionCapturada = textoMultiStringCalculation[i];
            }

        } else if (textoMultiStringCalculation[i] == ' ')
        {
            // Debug.Log(textoMultiStringCalculation[i] + " es espacio");

        } else if (textoMultiStringCalculation[i] == 's')
        {
            //Debug.Log(textoMultiStringCalculation[i] + " es stat(" + Stat + ")");
            if (operacion == false)
            {

                if (negativo == true)
                {
                    resultado -= Stat;
                    negativo = false;
                }
                else
                {
                    //Debug.Log("resultado += Stat(" + Stat + ")");
                    resultado += Stat;
                }
            }
            else
            {
                resultado = operar(resultado, operacionCapturada, Stat);
            }

        }
    }

    if (resultado < 0)
    {
        textoMultiString = "" + resultado;
    }
    else {
        textoMultiString = "+" + resultado;
    }
   
}

public int operar(int parametro1, char charOperacion, int parametro2) {

    switch (charOperacion) {
        case '-':
            return parametro1- parametro2;
        case '+':
            return parametro1 + parametro2;
        case '/':
            return parametro1 / parametro2;
        case '*':
            return parametro1 * parametro2;
    }

        return 0;
}

它几乎就在那里,“s”是统计数据(在本例中为 20)但我有一个问题,操作不是“数学”顺序

例子

"(20 - 10) / 2" = 5 => 解析为错误(我还没有解析 "(" 或 ")")

"20 - 10 / 2" = 15 => 解析为 "20 - 10" = 10 | 10/2 = 5 | 结果 = 5 (这是不正确的)

我不知道如何继续使它能够从正确的顺序进行组合数学运算

标签: c#unity3d

解决方案


计算给定表达式有一个小而简单的技巧:

DataTable table = new DataTable();
double d = (double)table.Compute("(20 - 10) / 2", null);

推荐阅读