Haskell 需要从列表中生成可能的树
我想从一个int列表中生成所有可能的树,但是我只生成一棵树Haskell 需要从列表中生成可能的树,haskell,tree,enumeration,template-haskell,catalan,Haskell,Tree,Enumeration,Template Haskell,Catalan,我想从一个int列表中生成所有可能的树,但是我只生成一棵树 1 1 2 2 3 5 4 14 5 42 就像这些加泰罗尼亚数字。如果我的列表大小是3,我想生成5棵可能的树,如果4-14棵可能的树 代码: data T = N T T | L Int deriving (Show) toT :: [Int] -> T toT [] = L 0 toT [n] = L n toT ns = T (
1 1
2 2
3 5
4 14
5 42
就像这些加泰罗尼亚数字。如果我的列表大小是3,我想生成5棵可能的树,如果4-14棵可能的树
代码:
data T = N T T | L Int deriving (Show)
toT :: [Int] -> T
toT [] = L 0
toT [n] = L n
toT ns = T (toT (take mid ns)) (toT (drop (mid+1) ns))
where
mid = length ns div 2
例如:toT[1..3]
输出:N(l1)(N(l2)(l3))
和N(N(l1)(l2))(l3)
现在,他这样做了
toTree [] = error "!!"
toTree [n] = Leaf n
toTree ns = Node leftTree rightTree
where
leftTree = toTree $ take (length(ns)-1) ns
rightTree = toTree $ drop (length(ns)-1) ns` ı want ns length contiue descend one point recursive but ı didnt
ı怎么能做到这一点?在递归中,ı将发送相同的列表,但长度将下降ı发送[1,2,3]大小3再次ı发送[1,2,3]长度2我更新了您的代码,它似乎对我有效。你能检查一下这是否符合你的期望吗
import Data.List
data Tree = Node Tree Tree | Leaf Int deriving (Show)
toTree :: [Int] -> Tree
toTree [] = Leaf 0
toTree [n] = Leaf n
toTree ns = Node leftTree rightTree
where midIndex = (length ns) `div` 2
leftTree = toTree $ take midIndex ns
rightTree = toTree $ drop (midIndex+1) ns
allTrees :: [Int] -> [Tree]
allTrees xs = map toTree $ permutations xs
main = print $ allTrees [1..4]
需要做的是,列表需要在每个可能的点进行拆分,这样做会使列表变小。子列表的树需要累加,然后所有的东西都要合并
data Tree
= L {-# UNPACK #-} !Int
| N !Tree !Tree
deriving (Eq, Ord, Read, Show)
-- Convert a list of Ints into a list of Trees containing the given list.
toTrees :: [Int] -> [Tree]
-- We start with the base cases: 0 and 1 elements. Because there are no
-- trees of 0 length, it returns the empty list in that case.
toTrees [] = []
toTrees [x] = [L x]
-- There is at least two elements in this list, so the split into nonempty
-- lists contains at least one element.
toTrees (x:xs@(y:ys)) = let
-- splitWith uses a difference list to accumulate the left end of the
-- split list.
splitWith :: ([a] -> [a]) -> [a] -> [([a], [a])]
splitWith fn [] = []
splitWith fn as@(a:as') = (fn [], as):splitWith (fn . (:) a) as'
-- Now we use a list comprehension to take the list of trees from each
-- split sublist.
in [
N tl tr |
(ll, lr) <- ([x], xs):splitWith ((:) x . (:) y) ys,
tl <- toTrees ll,
tr <- toTrees lr
]
只要看一下toTree的类型,很明显它不能满足“生成所有可能的树”的期望。谢谢,但是这生成了[1..3]6树,但是对于[1..3](nl1)(N(L2)(L3))和N(L1)(L2)(L3))实际上有N*C(n-1)具有n片叶子的不同树木;C(n-1)个形状,n!在叶子中放置n个整数的方法。这也不像将列表一分为二那么简单;每个子树中都有k=1,…,n-1个叶子的形状,而不仅仅是每个子树中有n/2个叶子。@chepner显示的可能树形状的数目对应于二叉树,二叉树将值存储在节点中并有空叶子:
data tree a=Branch a(tree a)(tree a)| empty
。在您的示例中,为3个整数显示了两个可能的树形状,使用数据类型,但前面提到的是5(表中也显示了5)。数据类型或表格哪一个是正确的?类似于此的表格大小为1树1、大小为2树1、大小为3树2、大小为4树5大小为5树14。对于msitake
GHCi> toTrees [1, 2, 3, 4, 5]
[N (L 1) (N (L 2) (N (L 3) (N (L 4) (L 5)))),N (L 1) (N (L 2) (N (N (L 3) (L 4)) (L 5))),
N (L 1) (N (N (L 2) (L 3)) (N (L 4) (L 5))),N (L 1) (N (N (L 2) (N (L 3) (L 4))) (L 5)),
N (L 1) (N (N (N (L 2) (L 3)) (L 4)) (L 5)),N (N (L 1) (L 2)) (N (L 3) (N (L 4) (L 5))),
N (N (L 1) (L 2)) (N (N (L 3) (L 4)) (L 5)),N (N (L 1) (N (L 2) (L 3))) (N (L 4) (L 5)),
N (N (N (L 1) (L 2)) (L 3)) (N (L 4) (L 5)),N (N (L 1) (N (L 2) (N (L 3) (L 4)))) (L 5),
N (N (L 1) (N (N (L 2) (L 3)) (L 4))) (L 5),N (N (N (L 1) (L 2)) (N (L 3) (L 4))) (L 5),
N (N (N (L 1) (N (L 2) (L 3))) (L 4)) (L 5),N (N (N (N (L 1) (L 2)) (L 3)) (L 4)) (L 5)]
GHCi> length it
14