Простая библиотека или реализация для оценщика математических выражений
У меня есть один текстовый файл, содержащий только одну строку, строка содержит только одно математическое выражение
например, 12+ (3,0 * (4) -1)/sqrt (121)
моя программа должна прочитать это выражение как строку, а затем дать результат
13
есть ли какой-либо простой способ или сторонняя dll/lib, чтобы это сделать?
КОММЕНТАРИЙ ДОБАВЛЕН:
Оценка строки простых математических выражений
вот решение, но многие из решений содержат только + -/* acturally, мне нужны операторы как можно больше, такие как квадратный корень квадрата и мощность()
так что эта ссылка может быть лучшим решением
http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx
Ответы
Ответ 1
Используя 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 = "12 + (3.0 * (4) - 1) / sqrt(121)";
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;
}
Ответ 2
.NET-решения:
Здесь пара тем на SO:
Также два проекта, которые я уже использовал раньше:
С#: NCalc - Оценщик математических выражений для .NET
NCalc - это оценщик математических выражений в .NET. NCalc может анализировать любое выражение и оценивать результат, включая статические или динамические параметры и пользовательские функции.
VB.NET: Быстрое облегчение оценки экспрессии
Flee является парсером выражения и оценщиком для платформы .NET. Он позволяет вам вычислить значение строковых выражений, таких как sqrt (a ^ 2 + b ^ 2) во время выполнения. Он использует собственный компилятор, строго типизированный язык выражения и легкий код для компиляции выражений непосредственно в IL. Это означает, что оценка экспрессии очень быстро и эффективно. Попробуйте demo, который позволяет создавать изображения на основе выражений и видеть сами.
Вы можете использовать его с С#, так как он в любом случае (через ссылку на сборку).
Ответ 3
Для C et al, здесь быстрый n-грязный и очень опасный чит, который требует Perl:
double eval(const char* expr) {
char buf[1024];
snprintf(buf, sizeof(buf), "perl -e 'print (%s)'", expr);
FILE* p = popen(buf, "r");
double d;
fscanf(p, "%lf", &d);
fclose(p);
return d;
}
Ответ 4
В среде программирования UNIX, я думаю, это был простой калькулятор под названием hoc
(IIRC). Возможно, его исходный код доступен где угодно.
Приветствия и hth.,
Ответ 5
Я бы подумал о вложении lua. Его быстрый, легкий и ansi C. И он был специально разработан для встраивания. Используется многими играми как их язык сценариев. (IMO гораздо проще встраивать, чем python или perl)
Вот полный пример, показывающий, насколько тривиальным является
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include <string>
#include <iostream>
int main()
{
std::string expression = "12+(3.0*(4)-1)/math.sqrt(121)";
lua_State * L = lua_open();
luaopen_math(L);
if( luaL_dostring(L, ("return "+expression).c_str()) != 0 )
{
std::cout<<"ERROR : "<<lua_tostring(L,-1)<<std::endl;
}
if( lua_type(L,-1) == LUA_TNUMBER )
{
std::cout<<"GOT "<<lua_tonumber(L,-1)<<std::endl;
}
lua_close(L);
}
Ответ 6
Если вы хотите отважиться на исходный код, вы всегда можете посмотреть bc
. Он обрабатывает всю доброту Lex/Yacc для вас. И если вы хотите чистое решение на С++, вы можете попробовать кодирование в Boost Spirit.
Ответ 7
Для С++ попробуйте muParser:
muParser - быстрая библиотека математического анализатора