我想编写一个获取已排序列表列表的函数,然后将所有内容合并在一起并再次对它们进行排序。
到目前为止我设法写了这个:
merge_:: Ord a => [[a]] -> [a] --takes in the list and merges it
merge_ [] = []
merge_ (x:xs) = x ++ merge_ xs
isort:: Ord a => [a] -> [a] --Sorts a list
isort [] = []
isort (a:x) = ins a (isort x)
where
ins a [] = [a]
ins a (b:y) | a<= b = a:(b:y)
| otherwise = b: (ins a y)
我无法找到一种方法将这两者合并为一个有意义的方式。请注意,我不允许使用诸如('。','$'等)(家庭作业)之类的东西
答案 0 :(得分:5)
我们开始简单。我们如何合并两个排序列表?
mergeTwo :: Ord a => [a] -> [a] -> [a]
mergeTwo [] ys = ys
mergeTwo xs [] = xs
mergeTwo (x:xs) (y:ys)
| x <= y = x : mergeTwo xs (y:ys)
| otherwise = y : mergeTwo (x:xs) ys
我们如何合并多个?好吧,我们从第一个和第二个开始并将它们合并在一起。然后我们将新的和第三个合并在一起:
mergeAll :: Ord a => [[a]] -> [a]
mergeAll (x:y:xs) = mergeAll ((mergeTwo x y) : xs)
mergeAll [x] = x
mergeAll _ = []
奥莱特。现在,要对所有元素进行排序,我们需要从每个元素创建一个列表,然后将它们合并。让我们编写一个为单个项目创建列表的函数:
toList :: a -> [a]
toList x = -- exercise
现在是一个包含列表中所有元素的函数:
allToList :: [a] -> [[a]]
allToList = -- exercise
现在我们已经完成了。我们只需要使用allToList
然后使用mergeAll
:
isort :: Ord a => [a] -> [a]
isort xs = mergeAll (allToList xs)
请注意,这项练习变得更加容易,因为我们已将其分为四个功能。
toList
和allToList
。allToList
的列表理解。请为allToList
尝试更高阶的功能。isort
无点((.)
)。toList
函数。使用那个。mergeAll
foldr
答案 1 :(得分:0)
试试这个(未经测试):
merge :: Ord a => [a] -> [a] -> [a]
merge [] l1 = l1
merge l1 [] = l1
merge (e1:l1) (e2:l2)
| e1<e2 = e1:merge l1 (e2:l2)
| otherwise = e2:merge (e1:l1) l2