Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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#_Algorithm_Math - Fatal编程技术网

C# 公式和数学表达式解析器算法

C# 公式和数学表达式解析器算法,c#,algorithm,math,C#,Algorithm,Math,我必须写一个程序,能够解析公式。 它的工作原理如下所示: 输入:5x+7^sin(z)/2T+44 输出:输入x、z、t的值 输入:2,1,2 输出:答案是:某物 它应该支持(+、*、-、^、%,SIN,COS) 我确实读过关于调车场算法的那一页 我还知道如何将中缀表达式转换为后缀或前缀。 这是我的算法: 1-给出表达式2-如果 括号是平衡,请转至步骤3 否则显示错误转到步骤13- 查找除(SIN, COS)4-从 输入5-替换变量6 -为表达式添加前缀并计算它7-在输出中显示结果 并关闭

我必须写一个程序,能够解析公式。 它的工作原理如下所示:

输入:5x+7^sin(z)/2T+44
输出:输入x、z、t的值
输入:2,1,2
输出:答案是:某物


它应该支持(+、*、-、^、%,SIN,COS)
我确实读过关于调车场算法的那一页

我还知道如何将中缀表达式转换为后缀或前缀。
这是我的算法:

1-给出表达式
2-如果 括号是平衡,请转至步骤3 否则显示错误转到步骤1
3- 查找除(SIN, COS)
4-从 输入
5-替换变量
6 -为表达式添加前缀并计算它
7-在输出中显示结果 并关闭程序


是这样吗?我想在C#
中实现它,请告诉我任何对我有用的注意事项。

我不知道如何在C#中实现它,但是python有一个非常强大的语法树分析器(ast模块),如果您将表达式作为python表达式给出,它可以在这里帮助您(这并不难,只需添加“*”乘法符号即可:-)

首先,定义只重新定义
visit\u Name
方法的好类(为标识符调用,例如为表达式调用另一个
visit\u Expr
visit\u Num
在满足数字时调用,等等,这里我们只需要标识符)

然后定义一个快速函数,该函数使用表达式为您提供其标识符:

>>> def visit(expression):
    node = ast.parse(expression)
    v = MyVisitor()
    v.visit(node)
    print v.identifiers
看起来还可以:

>>> visit('x + 4 * sin(t)')
['x', 't']
>>> visit('5*x + 7 ^ sin(z) / 2*T + 44')
['x', 'z', 'T']

将python 2.6或2.7用于ast模块。

查看这些视频。这些视频都是C语言的,有很好的解释


  • 如果你决定从头开始写,你的算法看起来不错。我将提供一些我的想法

    您可能希望将步骤5(替换变量)移动到步骤6(为表达式添加前缀并进行计算)。换句话说,不只是对变量进行文本查找和替换,而是在计算过程中,在需要计算变量时进行查找和替换。这可能会在以后打开更多的可能性,可能会使绘制函数图或使用依赖于其他变量的值的变量变得更容易。不过,你的方法应该适用于简单的情况

    sin
    cos
    函数的一种可能实现方式是使用
    字典
    ,类似于:

    private var functions = 
        new Dictionary<string, Func<double,double>>(StringComparer.OrdinalIgnoreCase)
        {
            { "sin", Math.Sin },
            { "cos", Math.Cos },
            { "sec", Secant }
        };
    
    . . . 
    
    // checking whether a token is a defined function or a variable
    if (functions.ContainsKey(token))
    {
        // determine the value of the argument to the function
        double inputValue = getArgument();
        double result = functions[token](inputValue);
        . . .
    }
    
    . . .
    
    private static double Secant(double x)
    {
        return 1.0 / Math.Cos(x);
    }
    
    专用变量函数=
    新字典(StringComparer.OrdinalIgnoreCase)
    {
    {“sin”,数学,sin},
    {“cos”,Math.cos},
    {“秒”,正割}
    };
    . . . 
    //检查标记是已定义的函数还是变量
    if(functions.ContainsKey(令牌))
    {
    //确定函数的参数值
    double inputValue=getArgument();
    双结果=函数[token](inputValue);
    . . .
    }
    . . .
    专用静态双正割(双x)
    {
    返回1.0/Math.Cos(x);
    }
    
    您可以使用ANTLR,请参见此。可能与
    private var functions = 
        new Dictionary<string, Func<double,double>>(StringComparer.OrdinalIgnoreCase)
        {
            { "sin", Math.Sin },
            { "cos", Math.Cos },
            { "sec", Secant }
        };
    
    . . . 
    
    // checking whether a token is a defined function or a variable
    if (functions.ContainsKey(token))
    {
        // determine the value of the argument to the function
        double inputValue = getArgument();
        double result = functions[token](inputValue);
        . . .
    }
    
    . . .
    
    private static double Secant(double x)
    {
        return 1.0 / Math.Cos(x);
    }