【问题标题】:Expression Tree of logical expression逻辑表达式的表达式树
【发布时间】:2020-06-04 19:35:59
【问题描述】:

我需要改变这个:(a < b)∧(b < c)∨(c < d) 表达式转换为表达式树,但我想不出一种看起来正确的方法。这是我得到的:

【问题讨论】:

    标签: data-structures tree logic


    【解决方案1】:

    我预计这将是一个很长的答案,因为我将通过总体思考过程来实现解决方案。对于住院病人来说,解决方案在最后。

    你的解决方案正确吗?

    嗯,这取决于。如果 优先于,则您的图片将完全正确,在这种情况下,您只需在(b < c) ∨ (c < d) 有结果后应用。如果你像这样使用括号强制优先级也是正确的:

    (a < b) ∧ ( (b < c) ∨ (c < d) )
    

    也就是说,在谈论operator precedence 时,通常∧/and 优先于∨/or。当优先级相同时,计算从左到右进行,即右侧取决于左侧的结果。

    运算符的优先级越高,它在树中出现的越低。

    答案的其余部分将假定通常的运算符优先级。

    如何解决这个问题?

    解决这类问题的最佳方法是分解表达式。更好的是,如果我们使用prefix/polish notation 进行分解,那么以后构建树会更自然。

    给定:(a &lt; b) ∧ (b &lt; c) ∨ (c &lt; d)

    让我们把它分解成几部分:

    x = (a < b), which translates to prefix: < a b
    y = (b < c), which translates to prefix: < b c
    z = (c < d), which translates to prefix: < c d
    

    我们现在有 3 个不等式表达式,分解为 xyz

    现在是逻辑运算符。

    i = x ∧ y, which translates to prefix: ∧ x y
    j = i ∨ z, which translates to prefix: ∨ i z
    

    我们现在有 2 个逻辑表达式分解为 ij。请注意它们如何依赖于xyz。而且,j 依赖于i。依赖关系很重要,因为您知道树叶没有依赖关系。

    如何构建树?

    总结一下,这就是我们从原始表达式中分解出来的:

    x = < a b
    y = < b c
    z = < c d
    i = ∧ x y
    j = ∨ i z
    

    让我们自下而上地处理它。

    考虑到依赖关系,叶子显然是最独立的元素:abcd

    让我们构建树的底部,考虑这些独立元素在我们刚刚进行的分解中的所有出现(bc 出现两次,我们放了两次)。

    a   b   b   c   c   d
    

    现在让我们构建 xyz,它们仅依赖于 abcd。我将使用 /\ 来构建我的 ASCII 艺术作品,就像你的图片行一样。

      x       y       z
      <       <       <
     / \     / \     / \
    a   b   b   c   c   d
    

    现在我们已经看到,i 仅依赖于 x 和 y。所以我们现在可以把它放在那里。我们现在还不能添加j,因为我们需要先添加i

          i
          ∧
        /   \
      x       y       z
      <       <       <
     / \     / \     / \
    a   b   b   c   c   d
    

    现在我们只是缺少j,这取决于iz

               j
               ∨
             /   \      
            /     \
          i        \
          ∧         \
       /     \       \
      x       y       z
      <       <       <
     / \     / \     / \
    a   b   b   c   c   d
    

    我们有一个完整的表达式树。如您所见,每个依赖级别都会产生一个树级别。

    为了完全准确,这棵树中的Breadth-First Search 必须考虑zi 处于同一级别,因此树的正确表示必须将z 高一级:

                j
                ∨
             /     \      
            /       \
          i          z
          ∧          <
       /     \      / \
      x       y    c   d
      <       <       
     / \     / \     
    a   b   b   c
    

    再说明一点,为了完全清楚,对于表达式(a &lt; b) ∧ ( (b &lt; c) ∨ (c &lt; d) ),分解结果将是:

    x = < a b
    y = < b c
    z = < c d
    j = ∨ y z
    i = ∧ x j
    

    这反过来会导致你图片中的树。

    希望这对您未来构建表达式树的努力有所帮助。

    【讨论】:

    • 感谢您的深入解释,这对我帮助很大。只有一件事,昨天我问我的导师我是否可以在树中多次使用同一个变量,他真的没有答案并告诉我不要这样做。我想不出不使用两次 b 和 c 的方法,所以他错了还是我错过了什么?
    • 简短的回答是肯定的。但是变量和树节点之间是有区别的。构建树时,您不能在两个父节点之间共享树节点,这将使其成为图而不是树。这并没有说明叶子树节点在其中包含什么。例如,叶树节点可以保存一个值(123"foo")或对变量的引用(ab)。在评估树时,如果找到带有变量的树节点,则在树外部的某个其他结构中查找变量的实际值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 2011-11-27
    • 2020-11-03
    • 1970-01-01
    相关资源
    最近更新 更多