【问题标题】:Simple library or implementation for a mathematical expression evaluator [closed]数学表达式评估器的简单库或实现[关闭]
【发布时间】:2011-04-29 11:00:58
【问题描述】:

我有一个文本文件,其中仅包含一行,该行仅包含一个数学表达式 例如 12+(3.0*(4)-1)/sqrt(121)

我的程序需要将此表达式读取为字符串,然后给出结果
13

是否有任何简单的方法或 3rd 方 dll/lib 来解决这个问题?

添加评论:

Evaluating a string of simple mathematical expressions

这是解决方案,但实际上许多解决方案仅包含 +-/* ,我需要尽可能多的运算符,例如天花板平方根和 power()

所以这个链接可能是最好的解决方案
http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx

【问题讨论】:

  • 你想使用C#、C++、 C?
  • 那么你想用什么语言来实现呢?
  • 我的猜测是:您在 C# 中执行此操作,但您不想排除任何基于 C、C++ 或 C++0x 的可能解决方案。
  • C#/C/C++/C++0x 它们中的任何一个都可以,但不要提供脚本或 VB ...解决方案,因为我想在我的 C C++ C# 项目中挂钩此功能.. ..
  • c expression Evaluator 的可能副本

标签: c# c++ c c++11


【解决方案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 的主题:


    还有两个我之前用过的项目:

    C#:NCalc - Mathematical Expressions Evaluator for .NET

    NCalc 是 .NET 中的数学表达式计算器。 NCalc 可以解析任何表达式并计算结果,包括静态或动态参数和自定义函数。


    VB.NET:Fast Lightweight Expression Evaluator

    Flee 是 .NET 框架的表达式解析器和求值器。它允许您在运行时计算字符串表达式的值,例如 sqrt(a^2 + b^2)。它使用自定义编译器、强类型表达式语言和轻量级代码生成器将表达式直接编译为 IL。这意味着表达式评估非常快速和高效。试试demo,它可以让您根据表情生成图像,并亲自查看。

    您可以将它与 C# 一起使用,因为它仍然是 .NET(通过程序集引用)。

    【讨论】:

    • 比较复杂,源码是VB,有没有这样的C#或者C++项目?
    【解决方案3】:

    对于 c++,试试 muParser:

    muParser - a fast math parser library

    【讨论】:

      【解决方案4】:

      如果您愿意勇敢地查看源代码,您可以随时查看bc。它为您处理所有 Lex/Yacc 的优点。如果你想要一个纯 C++ 解决方案,你可以尝试在Boost Spirit 中编码。

      【讨论】:

        【解决方案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】:

          UNIX 编程环境中,我认为是开发了一个名为hoc (IIRC) 的简单计算器。可能它的源代码几乎在任何地方都可用。

          干杯,

          【讨论】:

            【解决方案7】:

            对于 C 等人,这是一个需要 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;
            }
            

            【讨论】:

            • 如你所说,作弊。与其说是 C 不如说是 perl...
            • 如果你不介意进程开销并且它根本不需要 Perl,那就太好了——你可以调用其他东西作为子进程,例如重击snprintf(buf, sizeof(buf), "echo $((%s))", expr);.
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-17
            • 1970-01-01
            • 2010-12-05
            • 1970-01-01
            相关资源
            最近更新 更多