简体   繁体   English

我需要创建haskell函数,它返回所有可能的二叉树,给定一个整数列表

[英]I need to create haskell function, which returns all possible binary trees, given a list of integers

As the title says, I need this: 正如标题所说,我需要这个:

    getAllTrees :: [Int] -> [Tree Int]
    getAllTrees xs = undefined

where tree is 树在哪里

    data Tree x 
      = Null
      | Leaf x
      | Node (Tree x) x (Tree x)

I will appreciate any help, even the smallest clue :) Thanks 我会感激任何帮助,即使是最小的线索:)谢谢

I usually find it easiest to use the list monad for these kinds of problems. 我通常发现使用list monad来解决这些问题最容易。 We can define getAllTrees by reasoning as follows: 我们可以通过如下推理定义getAllTrees

The only tree of zero items is Null : 唯一的零项目树是Null

getAllTrees [] = return Null

There is also only one tree of one element, namely a Leaf : 一个元素中只有一棵树,即Leaf

getAllTrees [x] = return $ Leaf x

When we have more than one element, we can split the list in all possible ways to determine how we should branch, and then recursively generate the sub-trees from each list. 当我们有多个元素时,我们可以用所有可能的方式拆分列表以确定我们应该如何分支,然后从每个列表递归生成子树。 Let's say we have a function splits :: [a] -> [([a], [a])] that returns all ways of splitting a list, for example: 假设我们有一个函数splits :: [a] -> [([a], [a])]返回分割列表的所有方法,例如:

> splits [1..3]
[([],[1,2,3]),([1],[2,3]),([1,2],[3]),([1,2,3],[])]

We can then define the final case of getAllTrees by using the list monad. 然后我们可以使用list monad定义getAllTrees的最终情况。 This allows us to write code which sort of looks like like we're focusing on only one case, and the monad will give us all the combinations. 这允许我们编写类似于我们只关注一个案例的代码,monad将为我们提供所有组合。

getAllTrees xs = do
  (left, x : right) <- splits xs
  Node <$> getAllTrees left <*> pure x <*> getAllTrees right

The first line splits the input list and takes the first item from the second part as the middle element. 第一行拆分输入列表,并将第二部分中的第一项作为中间元素。 The case when the second part is empty doesn't match the pattern, so it gets discarded since that's how the list monad handles pattern match failures. 第二部分为空时的情况与模式不匹配,因此它被丢弃,因为列表monad处理模式匹配失败的方式。

The second line uses applicative syntax to say that we want the result to be a list of nodes, made from all combinations of sub-trees from the left list, the fixed middle element x , and all sub-trees from the right list. 第二行使用应用语法来表示我们希望结果是一个节点列表,由left列表中的子树的所有组合,固定的中间元素xright列表中的所有子树组成。

All that remains then is to implement splits . 剩下的就是实现splits Looking at the example above, it's easy to see that we can just take the inits and tails of the list and zip them together: 看看上面的例子中,可以很容易地看到,我们可以只取initstails的名单,并zip在一起:

splits xs = zip (inits xs) (tails xs)

Time for a quick sanity check in the interpreter: 是时候在口译员中进行快速的健全检查:

> mapM_ print $ getAllTrees [1..3]
Node Null 1 (Node Null 2 (Leaf 3))
Node Null 1 (Node (Leaf 2) 3 Null)
Node (Leaf 1) 2 (Leaf 3)
Node (Node Null 1 (Leaf 2)) 3 Null
Node (Node (Leaf 1) 2 Null) 3 Null
> length $ getAllTrees [1..5]
42

Looks like we're done! 看起来我们已经完成了! Some key lessons: 一些重要的经验:

  • Try to think about the small cases first, and build up from there. 首先考虑小案例,然后从那里开始构建。
  • The list monad is useful for code that needs to generate all combinations of things. 列表monad对于需要生成所有事物组合的代码非常有用。
  • You don't have to do everything at once. 您不必一次完成所有事情。 Dealing with the list splitting separately made the code much simpler than it would have been otherwise. 单独处理列表拆分使代码比其他方式更简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否可以在Haskell中创建一个函数,该函数返回数据类型的构造函数列表? - Is it possible to create a function in Haskell which returns a list of the constructors for a data type? 是否可以在Haskell中为已排序的二叉树树创建Functor实例? - Is it possible to create a Functor instance for sorted binary trees in Haskell? 二叉树的Haskell插入函数 - Haskell Insert function for Binary Trees 在Haskell中构造列表l中所有大于给定值v的所有整数的列表 - Construct a list of all the integers in a list l which are greater than a given value v in Haskell 定义一个函数,该函数将给定列表的所有可能排列作为对列表返回 - Define a function that returns all of the possible permutations of the given list as a list of pairs 我需要编写一个haskell函数,它复制字符串中每个字符的出现,两者都由用户给出。 - I need to write a haskell function which duplicates every occurrence of a character in a string, both given by the user. 二叉树Haskell - Binary Trees Haskell 所有可能存储值的二叉树 - All possible binary trees storing a value 在Haskell中创建可分割整数列表 - Create a list of divisible integers in haskell 如何在Haskell中编写一个函数,该函数接受一个I​​nts列表并返回该列表的所有连续子列表? - How can I write a function in Haskell that takes a list of Ints and returns all the contiguous sublists of that list?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM