c++ - evaluador - expresiones equivalentes primaria
¿Cuál es la mejor forma de evaluar expresiones matemáticas en C++? (11)
Cuál es la mejor manera de evaluar cualquier expresión matemática personalizada, por ejemplo
3+sqrt(5)+pow(3)+log(5)
Sé que incrustar Python en C ++ puede hacer eso; ¿Hay alguna forma mejor?
¡Gracias!
Aquí hay un enfoque escrito para las versiones recientes de Boost Spirit: http://agentzlerich.blogspot.com/2011/06/using-boost-spirit-21-to-evaluate.html
Desarrollé un analizador de expresiones simples en C ++ y Java. Por el momento, solo manejan operadores aritméticos +. -, / * pero no hay ninguna razón por la que no puedan ampliarse para dar cabida a más funciones.
Estos ejemplos simples usan el algoritmo yarda de maniobras para convertir las expresiones en notación polaca inversa y luego otro algoritmo simple basado en la pila para realmente evaluar la expresión.
Los ejemplos de código se pueden encontrar aquí .
Formatea una cadena como esta:
#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 el compilador de C ++ para compilar el código anterior en una biblioteca compartida. A continuación, cargue esa biblioteca compartida, resuelva la dirección de evaluate
, iníciela y obtenga el resultado.
He escrito un front-end sencillo y fácil de usar para Lua para evaluar expresiones aritméticas de C (y C ++ por supuesto). Ver http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#ae . Consulte también Analizador de expresiones matemáticas OpenSouce C / C ++ y ¿Qué es un analizador matemático rápido C u Objective-C?
La forma más fácil es usar una biblioteca externa. El más fácil que he encontrado es TinyExpr . Está escrito en C, por lo que debería ser muy fácil llamar desde C ++. Además, es solo un archivo fuente y un archivo de encabezado. Muy fácil de integrar. Puedes obtenerlo here .
La solución de su problema de ejemplo es simplemente:
#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;
}
Sé que incrustar Python en C ++ puede hacer eso
Podrías hacer eso, pero tendrías una gran dependencia para resolver un problema simple.
Mientras buscaba en una biblioteca una tarea similar, encontré libmatheval . Parece ser una cosa adecuada. Lamentablemente, GPL, que es inaceptable para mí.
No estoy seguro de por qué ''pow'' solo tiene un parámetro, pero utilizando la biblioteca ExprTk se puede obtener la siguiente solución simple :
#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;
}
No hay forma de hacerlo con una biblioteca estándar estándar en C ++, aunque existen muchos algoritmos de análisis que le permitirán evaluar expresiones como estas.
Si desea algunas referencias sobre buenos algoritmos de análisis sintáctico, considere consultar el Capítulo 14 sobre el análisis de expresiones en Programar abstracciones en C ++ (¡gratis y disponible en línea!), O considere estudiar el algoritmo de Dijkstra para el patio de maniobras . Ambos algoritmos mencionados aquí son simples de implementar y le permitirán evaluar expresiones con relativa facilidad.
Si le interesan algunas herramientas más duras para evaluar expresiones, considere buscar en las herramientas flex
y bison
GNU , que pueden construir analizadores potentes para este tipo de expresiones. Creo que la documentación de bison
incluso muestra cómo analizar y evaluar expresiones aritméticas, por lo que puede que ya haya hecho su trabajo por usted.
¡Espero que esto ayude!
muParserX es otro analizador de expresiones matemáticas C ++.
Boost.Spirit es una biblioteca de analizador de C ++.
Ejemplos:
- en su distribución: versión classic y versión current (busque "calc");
- en la wiki de Rosetta ;
- algunas applications usan.
Lepton es otra biblioteca de C ++ que puede hacer esto. Además de analizar y evaluar expresiones, también tiene algunas habilidades más avanzadas. Por ejemplo, puede calcular derivadas analíticas y puede hacer una simplificación algebraica básica de expresiones. La biblioteca es bastante pequeña y es de código abierto (licencia MIT).