在C ++中解析符号差异

时间:2014-10-17 18:07:11

标签: c++ parsing symbolic-math differentiation

我找到了这两个库:   - muparser   - symbolicc ++

第一个能够有效地解析数学表达式,这样只需最少的包装,我就可以创建一个解析器对象,以便

parser my_parser("1/2 * x^2");
cout<<myparser(2)<<endl;

会导致打印2.0。这很棒,但它只适用于双打,对吗?

第二个实现了Symbolic对象,因此在示例中我可以执行以下操作:

Symbolic x("x");
Symbolic x2 = x^2;
cout<<df(x2, x)<<endl;

导致2.0 * x。所以它能够区分表达式,这很好。

我需要做的是两者的混合!我需要一个函数进行解析然后区分,以便我可以做类似的事情:

 cout<<df("1/2 * x^2", "x")<<endl;

我希望它也打印出2.0 * x。

有可能做这样的事吗?原则上,如果muparser可以处理任何对象,我可以简单地在Symbolic对象上运行一个表达式,然后区分它们。但我无法做出像这样的工作。

还有其他解决方法吗?我需要一些带有表达式的输入字符串并返回带有该表达式派生的输出字符串。

谢谢!

1 个答案:

答案 0 :(得分:0)

这不是完整的答案,因为正如他们所说,TMTOWTDI。但是,为了能够使用Symbolic ++,您需要程序级访问 ...也就是说,您无法真正编写和编译

Symbolic x("x");
Symbolic x2 = x^2;

但你需要的东西(但 waaaaay 比以上更灵活)

if (there_is_x_symbol) {
    expr = Symbolic x("x");
}
if (raise_to_the_2nd_power) {
    expr = expr^2;
}

要以有机的方式执行此操作,您需要解析器,以及不会简单地导出evaluate()方法但允许您访问表达式树的解析器,示例

     ( multiply )
      /        \
  ( 2 )       ( square )
                 \
                ( x )

您可以递归评估:

left = myEvaluate(node.left)
right = myEvaluate(node.right)
if (node.op == multiply) {
    return left * right;
}
if (node.op == square ) {
    return right ^ 2;
}
...

muparser(和muparserX)库似乎不允许这样做。

还有其他一些代数解析器,例如this看起来很有希望。您可以使用供应商Parser算法,编写自己的Evaluator,使用Symbolic ++并输出Symbolic ++表达式。

你不需要深入了解语法就可以破解这样一个解析器 - 大多数只会生成一个Reverse Polish Notation堆栈,这就是你真正需要了解的所有内容。

在bocca al lupo : - )