如何评估任何给定的表达式

时间:2012-05-17 20:22:59

标签: c++ data-structures binary-tree

给定任何字符串表达式,如何填充树?

我有一个我被困住的作业。

我需要使用任何数据结构来评估以下表达式(( 5 * 10 ) /2 - (( 2 + 3) + 6))

使用堆栈,我能够验证字符串是否格式良好。但是,如何将各种值添加到树中,然后按顺序对其进行评估。

请告诉我有关如何阅读字符串((( 490 * 9 ) / 2)/5/6 - (( 2/4 + 3) + 6 * 5))

的任何提示

例如,当输入表达式中的第15个子字符串时,如何让(-)成为三者的根?如何确保(/)6表达式发生在(/)5等之后。

5 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

  

评估任何字符串[代表数学]表达式

你需要做三件事:

  • 为表示语言的抽象语法树定义类型
  • 为您的语法编写递归下降解析器
  • 为您的语法编写解释器

你可以很容易地做到这一点。

我会使用Haskell表示法,因为它很简洁,但如果你愿意,你可以翻译它。

您的语言类型:

data Exp = Op BinOp Exp Exp
         | Lit Int

data BinOp = Plus
           | Times
           | Div
           | Sub

现在,我们可以用这种语言为表达式编写一个解释器:

eval :: Exp -> Int
eval (Lit n)      = n
eval (Op o e1 e2) = 
   let v1 = eval e1
       v2 = eval e2
   in case o of
       Plus  -> v1 + v2
       Times -> v1 * v2
       Sub   -> v1 - v2
       Div   -> v1 / v2 -- note, may fail!

确定。这就是您所用语言的评估者。现在写一个递归下降解析器......

答案 2 :(得分:1)

括号表示操作顺序,类似于您使用堆栈确保匹配的所有内容,您可以解析这些匹配并将它们用作树中的元素,以创建用于评估的层次结构,其中运算符是每个广度级的括号匹配。

答案 3 :(得分:1)

编辑第二个:操作澄清,参见其他答案

答案 4 :(得分:1)

此处的其他答案包括将表达式树读入内存,但它们不包括在构建树后对树进行评估。

评估树的一般策略是树应该由节点和叶子组成,其中节点是具有子节点的运算符,而叶子是常量值。例如,表达式(((490 * 9)/ 2)/ 5/6 - ((2/4 + 3)+ 6 * 5))转换为树

                      -
                  /      \
                 /        \
              div          +
             /   \       /   \
          div     6     +     *
         /   \        /  \   / \
      div     5      div  3 6   5
     /   \          /   \
    *     2        2     4
  /   \
450    9

要评估此树,请从根目录开始。首先递归计算左子树和右子树,然后将运算符应用于两个子树计算的结果。每个叶子(数字)都评估自己。

在这种情况下,您将从根( - )开始,将左子树评估为73.5,将右子树评估为33.5,然后减去最终结果为40。

作为一个更精确的例子,让我们看看树的最左边的节点,在进行了几层递归调用之后。叶450的计算结果为450,叶9的计算结果为9,并且节点(* 450 9)(以类似Lisp的前缀表示法编写树的节点)的计算结果为4050.因此,从节点(/ (* 450 9) 2)开始,左递归调用求值为4050,右递归调用求值为2,表示整个节点求值为2025.只要在组合值之前从节点进行递归调用,并确保每个叶子对其自身求值,树评估很简单。