对于赋值,我需要编写一些Haskell代码,其中包含由无限整数列表组成的有限列表作为输入,每个列表单调递增。
现在,我需要将这些合并到一个命令整数的列表中。此外,某些整数可能出现在多个列表中:在输出列表中,每个整数可能只在列表中出现一次。
所以如果输入是例如[[1,2,6,10,28,40 ......] [3,4,10,28,100,...],[任意数量的列表] ]那么输出应该是[1,2,3,4,6,10,28,40,100 ......]
我有点卡在这里。我不知道如何有效地使用foldr
来合并列表。我想我应该比较每个列表的头部并从中列出一个新列表。
答案 0 :(得分:7)
您可以通过考虑合并两个无限排序列表来简化问题,然后尝试进行概括。该合并的框架将如下所示:
mergeSorted :: Ord a => [a] -> [a] -> [a]
mergeSorted [] ys = ys
mergeSorted xs [] = xs
mergeSorted (x:xs) (y:ys) = ???
你必须比较x和y,并做一些明智的事情,可能涉及对mergeSorted的递归调用:这看起来不太糟糕,对吧?
现在,让我们假设mergeSorted有效,您可以将两个无限排序列表转换为一个无限排序列表。如何将N个无限排序列表转换为单个排序列表?为什么,这是一个简单的折叠!只需将两个列表合并在一起,然后将第三个列表与该列表合并,然后将第四个合并到该列表中,依此类推。
mergeAll :: Ord a => [[a]] -> [a]
mergeAll xss = foldr ???
答案 1 :(得分:1)
我们可以通过unfoldr pull
({{1}重复从其中一个列表中拉出一个最小元素,合并任意一对无限单调增加列表(例如你有) }}在unfoldr
)中,带
Data.List
我们可以成对处理任何有限列表,将其长度减半:
pull (x:xs,y:ys) | x<y = Just (x, (xs,y:ys))
| x>y = Just (y, (x:xs,ys))
| x==y = Just (x, (xs, ys)) -- pull same from both (NB!)
要重复一个步骤,直到满足条件,pairs f (x:y:t) = f (x,y) : pairs f t
pairs _ t = t
:
until
不要忘记处理空列表案例。