编写此函数的正确(有效)方法是什么?

玛雅·维克多

以下函数返回从树的根节点到最深节点的可能路径的列表:

paths :: Tree a -> [[a]]
paths (Node element []) = [[element]]
paths (Node element children) = map (element :) $ concat $ map paths children

这在纸面上看起来效率很低,因为concat它的复杂性非常高是否可以在不使用中间数据结构(例如序列)的情况下以降低复杂性的方式重写此函数?

编辑:说实话,我知道可以通过以下方法避免concat的O(n)/ loop复杂性:

  1. 在进行递归操作时构建路径(列表);
  2. 仅当您达到上一个递归级别时,才将路径追加到全局“结果”列表中。

这是一个说明该算法的JavaScript实现:

function paths(tree){
    var result = [];
    (function go(node,path){
        if (node.children.length === 0)
            result.push(path.concat([node.tag]));
        else
            node.children.map(function(child){
                go(child,path.concat([node.tag]));
            });
    })(tree,[]);
    return result;
}
console.log(paths(
    {tag: 1,
    children:[
        {tag: 2, children: [{tag: 20, children: []}, {tag: 200, children: []}]},
        {tag: 3, children: [{tag: 30, children: []}, {tag: 300, children: []}]},
        {tag: 4, children: [{tag: 40, children: []}, {tag: 400, children: []}]}]}));

(实际上,这不是O(1)/迭代,因为我使用的Array.concat不是列表约束(JS没有内置列表),而是仅使用它会使每次迭代保持不变的时间。)

concat没有可怕的复杂性;它是O(n),其中n每个列表中除最后一个元素之外的元素总数。在这种情况下,除非更改结果的类型,否则我认为无论有没有中间结构,都不可能做得更好。在这种情况下,列表列表绝对没有共享的潜力,因此您别无选择,只能分配每个列表的每个“缺点”。这样做concatMap只会增加一个不变的因素开销,如果您能找到一种显着减少开销的方法,我会感到惊讶。

如果要使用某些共享(以结构惰性为代价),则确实可以切换到其他数据结构。这仅在树有点“忙”的情况下才重要。任何支持序列的类型snoc都可以。最简单的说,您甚至可以反向使用列表,因此您可以获得从叶子到根的路径,而不是相反的路径。或者您可以使用更灵活的东西,例如Data.Sequence.Seq

import qualified Data.Sequence as S
import Data.Sequence ((|>), Seq)
import qualified Data.DList as DL
import Data.Tree

paths :: Tree a -> [Seq a]
paths = DL.toList . go S.empty
  where
    go s (Node a []) = DL.singleton (s |> a)
    go s (Node a xs) = let sa = s |> a
                       in sa `seq` DL.concat . map (go sa) $ xs

编辑

正如Viclib和delnan指出的那样,我的原始答案存在问题,因为最低级别多次遍历。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

JavaScript:它可以工作,但是编写此函数的更有效方法是什么?

来自分类Dev

编写此程序的最有效方法是什么?(里面的细节)

来自分类Dev

R:用R编写此公式的最有效方法是什么?

来自分类Dev

在匿名函数内部使用此方法的有效解决方案是什么?

来自分类Dev

编写此查询的有效方法

来自分类Dev

有什么有效的方法可以在python中编写此代码

来自分类Dev

编写haskell函数的正确方法是什么

来自分类Dev

这是编写此方法的最有效方法吗?

来自分类Dev

编写此查询的更好/更有效的方法

来自分类Dev

编写此代码段的有效方法?

来自分类Dev

编写此算法的更有效方法?

来自分类Dev

编写Java卡小程序的有效方法是什么?

来自分类Dev

在python中以二进制输出编写的最有效方法是什么?

来自分类Dev

在python中以二进制输出编写的最有效方法是什么?

来自分类Dev

时间序列:为子集编写代码的最有效方法是什么?

来自分类Dev

在python中编写[1:20,25:30]的最有效方法是什么

来自分类Dev

启动此应用程序的最有效方法是什么?

来自分类Dev

编写此多条件if语句的正确方法是什么?

来自分类Dev

在“有效飞镖”之后捕捉错误和异常的正确方法是什么?

来自分类Dev

使用集中版本控制的正确/最佳/最有效的方法是什么?

来自分类Dev

编写jQuery函数的更有效方法

来自分类Dev

编写jQuery函数的更有效方法

来自分类Dev

用JavaScript声明函数的最有效方法是什么?

来自分类Dev

用变量参数调用函数的有效方法是什么?

来自分类Dev

在2D坐标ndarray上调用函数的最有效方法是什么?

来自分类Dev

本地时间函数的有效参数是什么?

来自分类Dev

在Android上没有用户登录的情况下验证有效负载的正确方法是什么?

来自分类Dev

有没有编写此查询的更有效方法?

来自分类Dev

过滤单个资源最有效的方法是什么?

Related 相关文章

  1. 1

    JavaScript:它可以工作,但是编写此函数的更有效方法是什么?

  2. 2

    编写此程序的最有效方法是什么?(里面的细节)

  3. 3

    R:用R编写此公式的最有效方法是什么?

  4. 4

    在匿名函数内部使用此方法的有效解决方案是什么?

  5. 5

    编写此查询的有效方法

  6. 6

    有什么有效的方法可以在python中编写此代码

  7. 7

    编写haskell函数的正确方法是什么

  8. 8

    这是编写此方法的最有效方法吗?

  9. 9

    编写此查询的更好/更有效的方法

  10. 10

    编写此代码段的有效方法?

  11. 11

    编写此算法的更有效方法?

  12. 12

    编写Java卡小程序的有效方法是什么?

  13. 13

    在python中以二进制输出编写的最有效方法是什么?

  14. 14

    在python中以二进制输出编写的最有效方法是什么?

  15. 15

    时间序列:为子集编写代码的最有效方法是什么?

  16. 16

    在python中编写[1:20,25:30]的最有效方法是什么

  17. 17

    启动此应用程序的最有效方法是什么?

  18. 18

    编写此多条件if语句的正确方法是什么?

  19. 19

    在“有效飞镖”之后捕捉错误和异常的正确方法是什么?

  20. 20

    使用集中版本控制的正确/最佳/最有效的方法是什么?

  21. 21

    编写jQuery函数的更有效方法

  22. 22

    编写jQuery函数的更有效方法

  23. 23

    用JavaScript声明函数的最有效方法是什么?

  24. 24

    用变量参数调用函数的有效方法是什么?

  25. 25

    在2D坐标ndarray上调用函数的最有效方法是什么?

  26. 26

    本地时间函数的有效参数是什么?

  27. 27

    在Android上没有用户登录的情况下验证有效负载的正确方法是什么?

  28. 28

    有没有编写此查询的更有效方法?

  29. 29

    过滤单个资源最有效的方法是什么?

热门标签

归档