Каков наилучший способ оценить математические выражения в C ++? - PullRequest
31 голосов
/ 25 февраля 2011

Каков наилучший способ оценки любого пользовательского математического выражения, например

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

Я знаю, что встраивание Python в C ++ может сделать это; есть ли лучший способ?

Спасибо!

Ответы [ 11 ]

19 голосов
/ 29 сентября 2015

Не знаю, почему '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;
}
4 голосов
/ 25 февраля 2011

Нет способа сделать это с помощью стандартной стандартной библиотеки в C ++, хотя есть много хороших алгоритмов синтаксического анализа, которые позволят вам оценивать выражения, подобные этим.

Если вам нужны ссылки на хорошие алгоритмы синтаксического анализа, попробуйте заглянуть в главу 14, посвященную синтаксическому анализу выражений, в Программирование абстракций на C ++ (бесплатно и доступно онлайн!), Или рассмотрите Дейкстры маневровый алгоритм . Оба упомянутых здесь алгоритма просты в реализации и позволяют сравнительно легко оценивать выражения.

Если вам интересны более жесткие инструменты для оценки выражений, рассмотрите инструменты flex и GNU bison, которые могут создавать мощные парсеры для этих выражений. виды выражений. Я считаю, что документация bison даже показывает вам, как анализировать и оценивать арифметические выражения, так что вы, возможно, уже сделали свою работу за вас.

Надеюсь, это поможет!

3 голосов
/ 01 марта 2012

muParserX - еще один синтаксический анализатор выражений C ++.

3 голосов
/ 25 февраля 2011

Boost.Spirit - это библиотека синтаксического анализатора C ++.

Примеры:

2 голосов
/ 01 мая 2013

Лептон - это еще одна библиотека C ++, которая может сделать это. В дополнение к синтаксическому анализу и оценке выражений, он также обладает некоторыми более продвинутыми способностями. Например, он может вычислять аналитические производные и может выполнять некоторое базовое алгебраическое упрощение выражений. Библиотека довольно маленькая и имеет открытый исходный код (лицензия MIT).

2 голосов
/ 25 февраля 2011

Я написал простой, легкий в использовании внешний интерфейс для Lua для оценки арифметических выражений из C (и C ++, конечно). См. http://www.tecgraf.puc -rio.br / ~ lhf / ftp / lua / # ae . См. Также Анализатор математических выражений OpenSouce C / C ++ и Что такое быстрый математический анализатор C или Objective-C?

1 голос
/ 03 декабря 2013

При поиске в библиотеке похожей задачи я обнаружил libmatheval .Кажется, это правильная вещь.К сожалению, GPL, что для меня неприемлемо.

1 голос
/ 23 февраля 2012

Я разработал простой синтаксический анализатор выражений в C ++ и Java.На данный момент они обрабатывают только арифметические операторы.-, / * но нет никаких причин, по которым их нельзя было бы расширить для размещения большего количества функций.

В этих простых примерах используется алгоритм шунтирующего двора для преобразования выражений в обратную польскую запись, а затем другой простой алгоритм на основе стекафактически вычислите выражение.

Примеры кода можно найти здесь .

1 голос
/ 27 июня 2011

Вот подход, написанный для последних версий Boost Spirit: http://agentzlerich.blogspot.com/2011/06/using-boost-spirit-21-to-evaluate.html

0 голосов
/ 25 августа 2016

Самый простой способ - использовать внешнюю библиотеку. Самый простой, который я нашел, это TinyExpr . Он написан на C, поэтому его очень легко вызывать из C ++. Кроме того, это только один исходный файл и один заголовочный файл. Очень легко интегрировать. Вы можете получить это здесь .

Решение вашего примера проблемы просто:

#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 ++ может сделать это

Вы могли бы сделать это, но вы бы столкнулись с огромной зависимостью, чтобы решить простую проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...