在C ++中评估数学表达式的最佳方法是什么?

时间:2011-02-25 10:01:35

标签: c++ math expression

评估任何自定义数学表达式的最佳方法是什么,例如

3+sqrt(5)+pow(3)+log(5)

我知道将Python嵌入到C ++中可以做到这一点;有没有更好的方法?

谢谢!

11 个答案:

答案 0 :(得分:19)

不确定为什么' pow' 只有一个参数,但使用ExprTk库可以获得以下简单解决方案:

#include <cstdio>
#include <string>
#include "exprtk.hpp"

int main()
{
   typedef exprtk::expression<double> expression_t;
   typedef exprtk::parser<double>         parser_t;

   std::string expression_string = "3 + sqrt(5) + pow(3,2) + log(5)";

   expression_t expression;

   parser_t parser;

   if (parser.compile(expression_string,expression))
   {
     double result = expression.value();

     printf("Result: %19.15\n",result);
   }
   else
     printf("Error in expression\n.");

   return 0;
}

答案 1 :(得分:4)

使用C ++中的现成标准库无法做到这一点,尽管有很多很好的解析算法可以让你评估像这样的表达式。

如果您想要一些关于良好解析算法的参考资料,请考虑在Programming Abstractions in C++ 中查看关于表达式解析的第14章(免费在线提供!),或考虑查看Dijkstra's shunting-yard algorithm。这里提到的两种算法都很容易实现,并且可以让您相对容易地评估表达式。

如果您对用于评估表达式的更多核心工具感兴趣,请考虑查看flexGNU bison工具,它们可以为这些类型的表达式构建强大的解析器。我相信bison文档甚至会向您展示如何解析和评估算术表达式,因此您可能已经为您完成了工作。

希望这有帮助!

答案 2 :(得分:3)

Boost.Spirit是一个C ++解析器库。

示例:

答案 3 :(得分:3)

muParserX是另一个C ++数学表达式解析器。

答案 4 :(得分:2)

我为Lua编写了一个简单易用的前端,用于评估C(和C ++)中的算术表达式。见http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#ae。另请参阅OpenSouce C/C++ Math expression parser LibraryWhat is a fast C or Objective-C math parser?

答案 5 :(得分:2)

Lepton是另一个可以执行此操作的C ++库。除了解析和评估表达式之外,它还具有一些更高级的功能。例如,它可以计算分析导数,并且可以对表达式进行一些基本的代数简化。该库非常小,它是开源的(麻省理工学院许可证)。

答案 6 :(得分:1)

这是为最新版本的Boost Spirit编写的方法: http://agentzlerich.blogspot.com/2011/06/using-boost-spirit-21-to-evaluate.html

答案 7 :(得分:1)

我在C ++和Java中开发了simple expression parser。目前他们只处理算术运算符+。 - ,/ *但没有理由不能扩展它们来容纳更多功能。

这些简单的例子使用分流码算法将表达式转换为反向波兰表示法,然后使用另一种简单的基于堆栈的算法来实际评估表达式。

可以找到代码示例here

答案 8 :(得分:1)

在图书馆搜索类似任务时,我找到了libmatheval。似乎是一件正确的事。不幸的是,GPL,这对我来说是不可接受的。

答案 9 :(得分:0)

格式化这样的字符串:

#include <boost/lexical_cast.hpp>
#include <string>
#include <math.h>

extern "C" {
std::string evaluate() { return boost::lexical_cast<std::string>(3+sqrt(5)+pow(3)+log(5)); }
}

调用C ++编译器将上述代码编译到共享库中。然后加载该共享库,解析evaluate的地址,调用它并获得结果。

答案 10 :(得分:0)

最简单的方法是使用外部库。我发现的最简单的是TinyExpr。它是用C语言编写的,因此从C ++调用它应该很容易。此外,它只有一个源文件和一个头文件。很容易集成。你可以得到它here

解决您的示例问题只是:

#include "tinyexpr.h"
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Result: %f\n", te_interp("3+sqrt(5)+pow(3,2)+log(5)", 0));
    return 0;
}
  

我知道将Python嵌入到C ++中可以做到这一点

你可以做到这一点,但是你要引入一个巨大的依赖来解决一个简单的问题。