哪个数据结构用来解决一个简单的数学方程

Which Data Structure used to solve a simple math equation

本文关键字:简单 一个 方程 数据结构 解决      更新时间:2023-10-16

当接受像(10+5*15)这样的表达式并遵循操作顺序时

如何最好地解决这样的问题?哪种数据结构是最好的?

谢谢。

我将使用Dijkstra的分流场算法来创建AST。

尝试使用递归下降解析表达式。这将给你一个关于操作顺序的解析树。

此任务的通常数据结构是堆栈。当您在做编译之类的事情时,创建抽象语法树是有用的,但对于简单的求值,它通常是多余的。

思考一下——什么是操作符?几乎所有操作符(+、-、*、/)都是二进制操作符。括号是深度构造函数;再往下一层用括号括起来。

实际上,构造解决这个问题所需的数据的将是您最大的障碍。

这是在Java中,但它似乎从中缀转换为后缀,然后使用基于堆栈的方法进行计算。它将数字放入堆栈,到达操作符,然后从堆栈中取出两个数字,用操作符(x +/-)对它们求值。

http://enel.ucalgary.ca/People/Norman/enel315_winter1999/lab_solutions/lab5sol/exF/Calculator.java

转换方法如下:

  • 从左到右扫描中缀字符串对的。
  • 初始化一个空栈
  • 如果扫描的字符是操作数,则将其添加到后缀字符串中。如果扫描的字符是一个操作符并且堆栈为空
  • 将字符推入堆栈。
    • 如果扫描到的字符是操作数且堆栈不为空,则将该字符的优先级与堆栈顶部的元素(topStack)进行比较。如果topStack的优先级高于扫描字符,则弹出堆栈,否则将扫描字符推入堆栈。重复此步骤,只要stack不为空并且topStack优先于字符。
  • 重复此步骤,直到所有字符被扫描。(在扫描完所有字符后,我们必须将堆栈中可能包含的任何字符添加到后缀字符串中。)
  • 如果stack不为空,将topStack添加到后缀字符串和弹出堆栈。重复这个步骤,只要堆栈是不是空的。
  • 返回后缀字符串
  • 计算后缀字符串

如果你需要简单地计算作为字符串可用的表达式的结果,那么我就不需要任何数据结构,只是像这样的函数:

//
// expression ::= addendum [ { "-" | "+" } addendum ]
// addendum ::= factor [ { "*" | "/" } factor ]
// factor ::= { number | sub-expression | "-" factor }
// sub-expression ::= "(" expression ")"
// number ::= digit [ digit ]
// digit ::= { "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" }
//
int calcExpression(const char *& p);
int calcDigit(const char *& p);
int calcNumber(const char *& p);
int calcFactor(const char *& p);
int calcAddendum(const char *& p);

,其中每个函数只接受从它读取的const char *引用(指针自增),并返回结果的数值,在出现问题时抛出异常。

这种方法不需要任何数据结构,因为使用c++堆栈作为中间结果。作为一个例子…

int calcDigit(const char *& p)
{
    if (*p >= '0' && *p <= '9')
        return *p++ - '0';
    throw std::runtime_error("Digit expected");
}
int calcNumber(const char *& p)
{
    int acc = calcDigit(p);
    while (*p >= '0' && *p <= '9')
        acc = acc * 10 + calcDigit(p);
    return acc;
}

如果你需要编写一个编译器来将字符串(例如包括变量或函数调用)转换为代码或字节码,那么最好的解决方案可能是开始使用通用的n向树或具有不同AST节点类型的特定结构的树。