首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用高阶函数的Ltree逆交叉函数

利用高阶函数的Ltree逆交叉函数
EN

Code Review用户
提问于 2013-01-24 21:18:00
回答 1查看 95关注 0票数 1

我正在解决一些Haskell练习,作为刷新一些语言概念的方法。

我遇到以下情况:

代码语言:javascript
复制
data LTree a = Leaf a | Fork (LTree a) (LTree a)

crossing :: LTree a -> [(a,Int)]
crossing (Leaf x) = [(x,0)]
crossing (Fork e d) = map(\(x,y) -> (x,y+1)) (crossing e ++ crossing d)

上面的函数基本上是接受一个Ltree,并变成一个部分列表(列出树的叶子,以及它们的深度)。

练习是使一个函数build :: [(a,Int)] -> LTree a,它做crossing函数的逆函数,例如任何'a‘树的build (crossing a) = a

我到目前为止所做的事:

代码语言:javascript
复制
build :: [(a,Int)] -> LTree a
build l = fst (multConvert (map (\(x,n) -> (Leaf x, n)) l))

multConvert :: [(LTree a,Int)] -> (LTree a,Int)
multConvert [x] = x    
multConvert l = multConvert (convert l)

convert :: [(LTree a,Int)] -> [(LTree a,Int)]
convert [] = []
convert [x] = [x]
convert ((a,b):(c,d):xs) | b == d = ((Fork a c),(b-1)):xs
                         | otherwise = (a,b):convert ((c,d):xs)

基本上,我将crossing生成的列表转换为(LTree,a)列表,例如,[(3,3),(4,3)..]变成[(Leaf 3, 3), (Leaf 4, 3)...]convert函数将接受这个(LTree,a)列表,并将具有相同深度的连续元素转换为具有这两个元素的Fork。例如,[(Leaf 3, 3), (Leaf 4, 3), (Leaf 5, 2)...]变成了[(Fork (Leaf 3) (Leaf 4),2), (Leaf 5, 2)...]。注意,新产生的元素具有深度-1。

multConvert函数会一次又一次地在列表上应用上面的思想,直到这个列表只有一个元素。此元素将表示原始树。换句话说,我的算法使用自下而上的方法构建Ltree。

我想知道是否有更有力的方法来解决这个问题。例如,使用高阶函数,而不是显式递归(可能使用foldr)。

EN

回答 1

Code Review用户

回答已采纳

发布于 2013-01-24 22:01:09

我认为这是一个用于编写build的延续传递解决方案(简单解析器):

代码语言:javascript
复制
build :: [(a,Int)] -> LTree a
build xs = parseAt 0 xs fst

-- The first Int is the depth of the "root" of parseAt
parseAt :: Int -> [(a,Int)] -> ( (LTree a, [(a,Int)]) -> r ) -> r
parseAt r [] k = error "input too short"
parseAt r xs@((a,n):rest) k =
  case compare r n of
    GT -> error "depth too small"
    EQ -> k (Leaf a,rest)
    LT -> parseAt (succ r) xs (\ (left,rest1) ->
            parseAt (succ r) rest1 (\ (right,rest2) ->
              k (Fork left right, rest2)))
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/20878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档