我开始了解Haskell并一直密切关注http://learnyouahaskell.com的指南和https://wiki.haskell.org/How_to_work_on_lists的文档。我最近一直在使用节点和二叉树,并遇到了一个我似乎无法找出正确语法的问题。
如果我有一个有序的节点列表:
[(2 , Nil, Nil), (4, Nil, Nil), (10, Nil, Nil)]
我想在列表中插入一个新节点(3, Nil, Nil)
,以便它可以表示为:
[(2, Nil, Nil), (3, Nil, Nil),(4, Nil, Nil), (10, Nil, Nil)]
这样做最优雅的解决方案是什么?从我所看到的here看来,一旦检测到正确的位置,你就必须将列表分成两部分,但作为初学者,我不知道如何做到这一点。显然,伪代码将是For every Node in the list, compare its number value versus the count value of the new Node . Once this value is greater than or equal to the current index, split the list into two parts (a and b) and then combine the list in this order a ++ [newElement] ++ b
。
在我的脑海中(再次,在初学者级别)尝试实现它时,它看起来像:
sortedInsert
答案 0 :(得分:3)
模式匹配是常用的。
这是一般情况:
insertOrdered :: Ord a => a -> [a] -> [a]
insertOrdered a [] = [a]
insertOrdered a bs'@(b:bs)
| a <= b = a : bs'
| otherwise = b : insertOrdered a bs
轮到你了:用你的一些代码替换undefined;)
Nil
是什么,你必须使它成为Ord
的实例,或者你必须更改函数才能直接处理元组的第一个组件我选择使用:
data Nil = Nil
deriving (Show, Eq, Ord)
它将按原样运行:
λ> let xs = [(2 , Nil, Nil), (4, Nil, Nil), (10, Nil, Nil)]
λ> insertOrdered (3,Nil,Nil) xs
[(2,Nil,Nil),(3,Nil,Nil),(4,Nil,Nil),(10,Nil,Nil)]
但也许你必须为此改变这个:
insertOrdered :: Ord a => (a,b,c) -> [(a,b,c)] -> [(a,b,c)]
insertOrdered x [] = undefined
insertOrdered x@(a,_,_) ((a',_,_):ys)
| a <= a' = undefined
| otherwise = undefined -- probably something with insertOrdered?
答案 1 :(得分:1)
我建议从简单列表开始,比如Nums列表。这是一个在列表中插入成员的函数,只要可以比较元素:
insertOrdered :: Ord a => a -> [a] -> [a] -- Ord means the elements of the list can be ordered
insertOrdered item [] = [item] -- Empty list, return list with a single argument
insertOrdered item (first:ls) -- Split list between first element and the rest of it
| item <= first = item : first : ls -- Append our item at the start and merge everything
| otherwise = first : (insertOrdered item ls) -- Merge the first element with the result of calling this again
您可以立即使用以下内容进行测试:
insertOrdered 1 [0, 2, 3] -- [0, 1, 2, 3]
现在它适用于简单的情况,你可以考虑你的难度。这意味着告诉Haskell您可以订购您输入的内容以及如何操作,您可以学习here。
答案 2 :(得分:0)
我的建议看起来很像Carsten's,但我认为使用辅助go
函数来避免必须手动传递x
参数更好一些常:
insertOrdered :: Ord a => x -> [a] -> [a]
insertOrdered x = go where
go [] = [x]
go all@(y:ys) | x < y = x : all
| otherwise = y : go ys