【问题标题】:Tree merge algorithm in HaskellHaskell中的树合并算法
【发布时间】:2015-12-27 14:27:58
【问题描述】:

我需要一个函数,它需要两棵树,检查树干上是否有任何共同的分支,如果可能的话,将这些树合并成一棵树。

如果rootLabels 相等,则可以认为节点相同。不能合并具有不同根的两棵树。可以合并两棵同根树,递归检查它们的分支是否可以合并。

任何人都可以建议函数merge(下)的实现,它通过test1test2(即函数返回True)?我确信有一个简单、优雅的解决方案,但目前它正在回避我。或者,我可以使用现有的库函数吗?

import Data.Tree

merge :: (Eq a) => Tree a -> Tree a -> Either (Tree a, Tree a) (Tree a)
merge = undefined

test1 :: Bool
test1 = 
    Node 'a' 
            [Node 'b' 
                [Node 'c' 
                    [], 
                Node 'g' 
                    []], 
            Node 'd' 
                []]
    `merge`
    Node 'a' 
            [Node 'b' 
                [Node 'c' 
                    [Node 'h'
                        []]], 
            Node 'e' 
                [Node 'f' 
                    []]]
    == 
    Right 
    (Node 'a' 
        [Node 'b' 
            [Node 'c' 
                [Node 'h'
                    []], 
            Node 'g' 
                []], 
        Node 'd' 
            [],
        Node 'e' 
            [Node 'f' 
                []]])

test2 :: Bool
test2 =  
    let l = Node 'a' []
        r = Node 'b' []
    in  l `merge` r == Left (l,r)

【问题讨论】:

  • 那么如果根是普通的而分支不是,会发生什么?
  • @n.m.然后结果将是一棵具有公共根的树,以及来自两棵原始树的所有分支。如果您看到test1,则左树有一个不在右树中的分支“d”。结果包含两棵树的所有分支,包括分支“d”。
  • @DanielWagner 我还没有通过类型检查的解决方案
  • 展示你已经拥有的东西。

标签: algorithm haskell tree


【解决方案1】:

我想我终于明白了;

merge :: (Eq a) => Tree a -> Tree a -> Either (Tree a, Tree a) (Tree a)
merge l r = 
    if rootLabel l == rootLabel r
        then Right $ merge' l r 
        else Left (l,r)

merge' :: (Eq a) => Tree a -> Tree a -> Tree a
merge' l r = l { subForest = foldl mergeNode (subForest l) (subForest r) }

mergeNode :: Eq a => [Tree a] -> Tree a -> [Tree a]
mergeNode [] y = [y]
mergeNode (x:xs) y 
    | rootLabel x == rootLabel y = x `merge'` y : xs
    | otherwise = x : xs `mergeNode` y

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2013-08-04
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多