Quelle est la meilleure façon d'évaluer les expressions mathématiques en C++?

Quelle est la meilleure façon d'évaluer une expression mathématique personnalisée, par exemple

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

je sais que l'intégration de Python dans C++ peut faire ça; y a-t-il un meilleur moyen?

Merci!

31
demandé sur templatetypedef 2011-02-25 13:01:35

11 réponses

coup de pouce.Spirit est une bibliothèque C++ parser.

exemples:

3
répondu aaz 2011-02-25 12:49:18

Je ne sais pas pourquoi 'pow' n'a qu'un paramètre, mais en utilisant le ExprTk bibliothèque on peut dériver le suivant simple solution:

#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;
}
19
répondu 2015-09-29 20:26:57

il n'y a aucun moyen de faire cela avec une bibliothèque standard disponible dans le commerce en C++, bien qu'il y ait beaucoup de bons algorithmes d'analyse là-bas qui vous permettront d'évaluer des expressions comme celles-ci.

si vous voulez des références sur les algorithmes d'analyse, pensez à regarder dans le Chapitre 14 sur l'analyse d'expression dans Abstractions de programmation en C++ (gratuit et disponible en ligne!), ou envisager d'examiner le triage de Dijkstra l'algorithme de . Les deux algorithmes mentionnés ici sont simples à mettre en œuvre et vous permettront d'évaluer les expressions avec une relative facilité.

si vous êtes intéressé par des outils plus hardcore pour évaluer les expressions, pensez à regarder dans les outils flex et GNU bison , qui peuvent construire des parseurs puissants pour ces sortes d'expressions. Je crois que la documentation bison montre même comment analyser et d'évaluer des expressions arithmétiques, alors vous pourriez avoir votre travail est déjà fait pour vous.

Espérons que cette aide!

4
répondu templatetypedef 2017-11-18 04:10:26

muParserX est un autre analyseur D'expression mathématique C++.

3
répondu wildart 2018-05-15 07:14:22

j'ai écrit un simple, facile à utiliser, front-end à Lua pour évaluer les expressions arithmétiques de C (et C++ bien sûr). Voir http://www.tecgraf.puc-rio.br / ~lhf/ftp/lua / #ae . Voir aussi OpenSouce C/C++ expression Mathématique parser et qu'est Ce qu'un rapide C ou Objective-C mathématiques de l'analyseur?

2
répondu lhf 2017-05-23 12:17:55

Lepton est une autre bibliothèque C++ qui peut faire cela. En plus de l'analyse et de l'évaluation des expressions, il a aussi quelques pouvoirs avancés. Par exemple, il peut calculer des dérivés analytiques, et il peut faire une simplification algébrique de base des expressions. La Bibliothèque est assez petite, et c'est open source (licence MIT).

2
répondu peastman 2013-04-30 22:54:27

voici une approche écrite pour les versions récentes de Boost Spirit: http://agentzlerich.blogspot.com/2011/06/using-boost-spirit-21-to-evaluate.html

1
répondu Rhys Ulerich 2011-06-26 20:24:43

j'ai développé un simple analyseur d'expression en C++ et Java. À l'heure actuelle, ils ne manipulent opérateurs arithmétiques +. - , / * mais il n'y a pas de raison pour qu'elles ne puissent pas être étendues à d'autres fonctions.

ces exemples simples utilisent l'algorithme shunting yard pour convertir les expressions en notation Polish inversée, puis un autre algorithme simple basé sur la pile pour evauler réellement l'expression.

Code

des échantillons peuvent être trouvés ici .

1
répondu AndyUK 2012-02-23 19:41:37

en cherchant une bibliothèque pour une tâche similaire, j'ai trouvé libmatheval . Semble être une bonne chose. Malheureusement, GPL, ce qui est inacceptable pour moi.

1
répondu Yury 2013-12-03 13:43:39

formater une chaîne comme celle-ci:

#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)); }
}

invoque le compilateur C++ pour compiler le code ci-dessus dans une bibliothèque partagée. Puis chargez cette bibliothèque partagée, résolvez l'adresse de evaluate , invoquez-la et obtenez le résultat.

0
répondu Maxim Egorushkin 2011-02-25 12:23:25

la façon La plus simple est d'utiliser une bibliothèque externe. Le plus facile que j'ai trouvé est TinyExpr . Il est écrit en C, donc il devrait être très facile d'appeler depuis C++. Aussi, c'est seulement un fichier source et un fichier d'en-tête. Très facile à intégrer. Vous pouvez l'obtenir ici .

résoudre votre problème d'exemple est juste:

#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;
}

je sais que l'intégration de Python dans C++ peut faire ça

vous pourriez faire cela, mais vous seriez en train de tirer dans une énorme dépendance pour résoudre un problème simple.

0
répondu yas777 2016-08-27 17:21:57