【问题标题】:is there any algorithm to analyze a mathematical function?有没有分析数学函数的算法?
【发布时间】:2023-03-17 17:48:01
【问题描述】:

我正在使用 C++ 编程语言开发一个应用程序来绘制数学函数,用户编写函数、域和范围。我将 Win32 API 与 Direct2D 一起使用,但我不知道如何让程序绘制用户选择的函数。例如,用户输入函数“f (x) = x + 1”,程序应该绘制一条线。是否有任何算法可以实现来分析输入的函数,从而能够绘制它?

【问题讨论】:

标签: c++ c algorithm math


【解决方案1】:

第一步是解析你从用户那里得到的字符串。这包括检查输入错误并提供有用的/描述性错误消息(例如“对不起,我不知道 ^ 字符的含义”),以便用户可以知道哪里出了问题并纠正他们的错误。这样做的结果应该是一组令牌;其中令牌由包含 ID(例如,常量、变量、左括号、右括号、加、减、乘、除...)和一些数据(如果需要)的结构表示(常量的值或变量名称)。

第二步,将token组织成一棵树;这样操作员令牌有孩子,这些孩子是操作员令牌操作的值。这可能需要使用运算符优先规则(如“BEDMAS” - 括号、指数、除法、乘法、加法和减法),以便“f(x) = x + 1 * 2”被视为“f(x) = x + (1 *2)”而不被视为“ f(x) = (x + 1) *2"。它还将涉及提供有用的/描述性的错误消息(例如“对不起,您的左括号太多而右括号不够”),以便用户可以知道出了什么问题并纠正他们的错误。例如,“f(x) = x * (2 + x) + 1”将变为:

         [+]
         / \
       [*] [1]
       / \
     [+] [x]
     / \
   [2] [x]

第三步(理论上是可选的)是优化树。可以预先计算具有常量的运算符(例如,“f(x) = x * (1 + 2)”可以变为“f(x) = x * 3”)。可以丢弃零的加法或减法(例如,“f(x) = x * 2 + 0)”可以变成“f(x) = x * 2”)。可以丢弃乘以零(例如“f(x) = x + (x * 0)”可以变成“f(x) = x”)。可以丢弃乘法或除法(例如,“f(x) = x + (x * 1)”可以变成“f(x) = x + x”)。除以零可以成为无穷大或成为有用/描述性错误消息。除以常数可以变成乘以常数(例如“f(x) = x / 4”可以变成“f(x) = x * 0.25”)。

第四步是以某种方式执行树。最简单的方法是自己解释树。为了这;从树根处的令牌开始;如果令牌是常量,则返回其值,否则计算子令牌的值,然后使用运算符令牌的类型来确定如何处理它们并返回该值。这自然是递归的。为了获得高性能,您可以将树转换为本机机器代码(JIT 编译器)。

请注意,计算机无法正确进行简单的数学运算。例如,如果您使用计算机可以理解的数据类型(例如 double)来表示“((x + 3) / 3 - x) * 100000 - 100000”之类的内容,您将得到非常错误的结果。问题是四舍五入(由于缺乏精度和/或有时需要无限精度)和溢出。为了解决这个问题,我建议使用有理数,其中一个数字以“numerator / denominator * 2**exponent”的形式表示为 3 个整数(例如,值 10 将表示为 5 / 1 * 2**1,而 10/3 将变为 5 / 3 * 2**1 )。使用可变大小的“大整数”作为整数,这可以避免所有问题(“内存不足”除外,只有当用户输入的字符串也非常大时才会发生这种情况)。

【讨论】:

  • 我就是这个意思,你知道有什么算法可以做到吗?
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
相关资源
最近更新 更多