【问题标题】:Recursively returning collection or element in collection递归返回集合或集合中的元素
【发布时间】:2016-05-27 04:28:24
【问题描述】:

这是一个简单的递归算法,用于从树的叶子生成嵌套列表:

/** Make a list from bottom level of equal path tree - list would be nested according
    to hierarchy in tree.

     1
    /  \
   2    3
   /\   |
  4  5  6
    ==>
    [[4, 5], 6]
 */
List leavesToList(TreeNode node) {
    List<TreeNode> children = node.getChildren()
    if (!children) {
        return node.getData() // Problem with static typing!!
    }
    if (children.size() == 1) {
        return leavesToList(children[0])
    }
    return children.collect {leavesToList(it)}
}

该算法适用于动态类型,但静态类型会导致问题为非列表 函数不能返回值。理想情况下,返回值 将是 Collection&lt;T&gt;|T 类型,但这样的类型规范是不可能的。

作为一项工作,我想到了一个像这样的包装器解决方案:

@CompileStatic
static List leavesToList(Tnode rnode) {
    Closure inner
    inner = { Tnode node ->
        List<Tnode> children = node.getChildren()
        if (!children) {
            return node.getData()
        }
        if (children.size() == 1) {
            return inner.call(children[0])
        }
        return children.collect { inner.call(it) }
    }
    return inner.call(rnode) as List
}

问题:

  • 包装器实现的效率是否低于原始实现? 例如,设置闭包是否有重复开销?

  • 作为一种通用技术(而不是特定于示例案例的技巧),是否存在 除了使用包装器之外,处理这种情况的更好方法是什么?

【问题讨论】:

    标签: java recursion groovy closures static-typing


    【解决方案1】:

    我希望我不会在这里遗漏一些东西,但为了静态类型,我会做这样的事情:

    @CompileStatic
    List leavesToList(TreeNode node) {
       List<TreeNode> children = node.children
       if (!children) {
          return [node.data]
       }
       if (children.size() == 1) {
          return leavesToList(children.first())
       }
       children.collect this.&leavesToList
    }
    

    基本上将data 包装到一个列表中。

    【讨论】:

    • 您的代码输出与问题所要求的不同。
    猜你喜欢
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 2016-07-09
    • 1970-01-01
    • 2020-03-24
    • 2012-09-19
    相关资源
    最近更新 更多