【问题标题】:Traverse/Transform the expression tree遍历/变换表达式树
【发布时间】:2015-09-11 11:51:24
【问题描述】:

我有一个表达式树,我需要遍历并生成某个字符串。 假设我有这棵树

     OR
    /  \
  AND   C
 /   \
A     B

我想把它变成:

(A AND B) OR C

我正在考虑使用顺序遍历,但这并不是我需要的。

【问题讨论】:

  • 你想用java或c#实现还是只用算法??用户适当的标签
  • 您认为顺序遍历有什么问题?
  • @Panther 语言并不重要,即使是伪代码也可以
  • @rici 访问节点的顺序不正确,请注意这里并非所有节点都包含值,
  • 在您的示例中,这是正确的顺序。一些节点是运算符,它们在左右子节点之间被正确访问。那么问题出在哪里?我们所说的有序是指不同的东西吗?

标签: java c# algorithm tree


【解决方案1】:

最简单的解决方案是打印多余的括号:

Visit(node):
  Output "("
  If node.has_left():
    Visit(node.left)
  Output node.label
  If node.has_right():
    Visit(node.right)
  Output ")"

要解决冗余括号问题,为每个运算符分配一个左右优先级,就像在运算符优先级解析中一样,并将父节点的优先级传递给访问。仅当访问节点的优先级低于从父节点传入的优先级时,访问才会输出括号。

【讨论】:

    【解决方案2】:
    abstract class Expression {
    }
    
    class Binary extends Expression {
    
        final String operator;
        final Expression left, right;
    
        Binary(String operator, Expression left, Expression right) {
            this.operator = operator;
            this.left = left;
            this.right = right;
        }
    
        @Override
        public String toString() {
            return String.format("(%s %s %s)", left, operator, right);
        }
    }
    
    class Variable extends Expression {
    
        final String name;
    
        Variable(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return name;
        }
    }
    
    @Test
    public void testExpression() {
        Expression e = new Binary("OR", new Binary("AND", new Variable("A"), new Variable("B")), new Variable("C"));
        System.out.println(e);
        // -> ((A AND B) OR C)
    }
    

    【讨论】:

    • 我不确定是否可以在这里看到任何遍历
    • 遍历是在隐式递归调用Binary.toString。在该方法中,String.format 的参数被转换为字符串。
    猜你喜欢
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多