Haskell - 合并排序,排序单词和数字

时间:2011-09-26 11:13:54

标签: haskell mergesort

我在Haskell中编写了一个合并排序,它在使用数字而不是单词时起作用,我认为它会。使用单词和字母时,我只是得到“不在范围内”。我做错了什么?

这是我的代码:

merge :: Ord a => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
    | x <= y = x : merge xs (y:ys)
    | otherwise = y : merge (x:xs) ys

mergeSort :: Ord a => [a] -> [a]
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs
    = merge (mergeSort top) (mergeSort bottom)
    where
    (top, bottom) = splitAt (length xs `div` 2) xs

2 个答案:

答案 0 :(得分:4)

你输入这样的话吗?

[this,is,an,example,sentence]

语法不正确。如果要输入文字字符串,则必须用双引号(")封装它:

["this","is","an","example","sentence"]

如果这不是您的错误,请随意忽略此答案。

答案 1 :(得分:3)

您的代码运行正常。

但是我建议在一次通过中拆分列表,而不使用length。当然,这里的顺序并不重要,只是我们有两个大小相同的列表。你可以这样做:

splitList [] = ([],[])
splitList [x] = ([x],[])
splitList (x:y:zs) = let (xs,ys) = splitList zs in (x:xs, y:ys)  

...或尾递归...

splitList zs = go zs [] [] where
   go [] xs ys = (xs, ys)
   go [x] xs ys = (x:xs, ys)
   go (x:y:zs) xs ys = go zs (x:xs) (y:ys)    

...或使用索引......

splitList xs = (go even, go odd) where
   go f = map snd $ filter (f.fst) $ indexed
   indexed = zip [0..] xs

......或使用折叠...

import Data.List

splitList zs = snd $ foldl' go (True,([],[])) zs where
   go (True,(xs,ys)) x = (False,(x:xs,ys))   
   go (False,(xs,ys)) x = (True,(xs,x:ys))