【问题标题】:How to build a tree sideways and downwards?如何在侧面和向下建造一棵树?
【发布时间】:2019-10-19 15:33:08
【问题描述】:

如何向下和水平地建造一棵树?

我现在有一棵树:

data Tree a = Node a [Tree a]

然后,我有一个根Int[Int] 的列表

1 and [2,3,4]

我想建一棵树

       1
    /  |  \
   2   3   4
  /\  / \  /\
 3  4 2 4 2  3
 |  | | | |  |
 4  3 4 2 3  2 

在 Haskell 中,它看起来像

Node 1 [Node 2 [Node 3 [Node 4 []],Node 4[Node 3 []]], Node 3 [Node 2 [Node 4 []], 
Node 4 [Node 2 []]], Node 4 [Node 2 [Node 3 []], Node 3 [Node 2 []]]]

这是我尝试过的: 这段代码使我的树向下生长

down :: Int -> [Int] -> Tree Int
down y [] = Node y []
down y (x:xs) = Node y [down x xs]

这段代码让我的树横向生长

side :: Int -> [Int] -> Tree Int
side y [] = Node y []
side y x = Node y $ map (\x -> Node x []) y

现在,我无法将它们拼凑在一起以获得上述解决方案。任何帮助表示赞赏

【问题讨论】:

  • 那么,树中的每条路径都只是[1,2,3,4] 的排列,它以1 开头?
  • @chepner 是的,没错
  • 你遇到了什么麻烦?
  • @MichaelLitchard 我不知道如何将向下和横向生长树的代码拼凑在一起以获得我想要的树
  • 棘手的部分是这样做不仅仅是两种技术的组合。每个级别可供选择的整数列表会因分支而异。

标签: haskell tree


【解决方案1】:

我们可以引入一个辅助函数pick,它将生成一个包含我们选择的项目的二元组列表,并返回剩余的列表。我们可以使用差异列表来实现这一点,但一个简单但效率较低的实现是:

import Data.List(tails, inits)

pick :: [a] -> [(a, [a])]
pick vs = [(x, ws ++ xs) | (ws, (x:xs)) <- zip (inits vs) (tails vs) ]

然后我们这样检索:

Prelude Data.List> pick [2,3,4]
[(2,[3,4]),(3,[2,4]),(4,[2,3])]

现在我们可以更改您的down 功能:

down :: a -> [a] -> Tree a
down y = Node y . map (uncurry down) . pick

对于给定的样本数据,我们得到:

Prelude Data.List> down 1 [2,3,4]
Node 1 [Node 2 [Node 3 [Node 4 []],Node 4 [Node 3 []]],Node 3 [Node 2 [Node 4 []],Node 4 [Node 2 []]],Node 4 [Node 2 [Node 3 []],Node 3 [Node 2 []]]]

【讨论】:

    猜你喜欢
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多