【问题标题】:How to create a math formula interpreter如何创建数学公式解释器
【发布时间】:2011-08-08 06:30:25
【问题描述】:

我必须用 PHP 创建一个简单的公式解释器。它必须支持 4 种运算符:exp、ln、加法、减法和括号。

我应该从哪里开始?听说用户输入的公式必须转化成树,是这样吗?也许口译员已经存在?

【问题讨论】:

标签: php interpreter


【解决方案1】:

是的,正确的用户输入的公式必须转换成abstract syntax tree

数学公式通常使用infix 表示法编写。您需要将其转换为 postfixprefix 表示法。 postfix 表示法也称为reverse polish notation

您可以使用shunting yard algorithm 来完成此操作。 See a detailed example.

stackoverflow question 链接到 PHP 中的实现。

【讨论】:

  • 如何验证用户输入并显示“无右括号”之类的错误?
  • 阅读the algorithm in detail部分调车场算法。它处理无效输入,例如不匹配的括号。
【解决方案2】:

您可能可以使用基本的字符串操作将公式重写为 PHP 表达式并eval 它。根据语法,您甚至可以不理会表达式,只为expln 定义PHP 函数,这样当您eval 输入时,可以直接对其求值。

这比为这种简单的语言编写自己的解析器和解释器要简单得多。

如果这是课堂作业,您的老师可能会因此而让您失望。

【讨论】:

  • 幸运的是,这不是课堂作业 :) Eval 听起来是一个不错的解决方案,但让用户执行自己的 PHP 代码很危险。我可能应该想出一个巨大的正则表达式来验证输入......
  • 应该是一个非常简单的正则表达式,不是吗?允许数字、+-expln、括号和空格。你不能用它来编写任何危险的 PHP 代码。
【解决方案3】:

这是我创建的,请查看:Formula Interpreter

它是如何工作的?

首先,使用公式及其参数创建FormulaInterpreter 的实例

$formulaInterpreter = new FormulaInterpreter("x + y", ["x" => 10, "y" => 20]);

使用execute() 方法解释公式。它将返回结果:

echo $formulaInterpreter->execute();

一行

echo (new FormulaInterpreter("x + y", ["x" => 10, "y" => 20]))->execute();

示例

# Formula: speed = distance / time
$speed = (new FormulaInterpreter("distance/time", ["distance" => 338, "time" => 5]))->execute() ;
echo $speed;


#Venezuela night overtime (ordinary_work_day in hours): (normal_salary * days_in_a_work_month)/ordinary_work_day
$parameters = ["normal_salary" => 21000, "days_in_a_work_month" => 30, "ordinary_work_day" => 8];
$venezuelaLOTTTArt118NightOvertime = (new FormulaInterpreter("(normal_salary/days_in_a_work_month)/ordinary_work_day", $parameters))->execute();
echo $venezuelaLOTTTArt118NightOvertime;


#cicle area
$cicleArea = (new FormulaInterpreter("3.1416*(radio*radio)", ["radio" => 10]))->execute();
echo $cicleArea;

关于公式

  1. 它必须至少包含两个操作数和一个运算符。
  2. 操作数的名称可以是大写或小写。
  3. 到目前为止,不包括 sin、cos、pow 等数学函数。我正在努力将它们包括在内。
  4. 如果您的公式无效,您将收到如下错误消息:错误,您的公式 (single_variable) 无效。
  5. 参数的值必须是数字。

如果你愿意,你可以改进它!

【讨论】:

    猜你喜欢
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多