2011-09-26 10 views
2

하스켈에서 병합 정렬을 작성했습니다. 숫자가 아닌 단어를 사용할 때 작동합니다. 그렇게 생각했습니다. 단어와 글자를 사용할 때 "범위가 맞지 않습니다"라는 메시지가 나타납니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?하스켈 - 병합 단어와 숫자 정렬하기

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 
+1

이것은 문자열, fe 'mergeSort [ "banana", "candy", "apple"]' –

+3

코드는 괜찮아 보입니다. 정확한 입력과 완전한 오류 메시지를 보는 것이 도움이 될 수 있습니다. * something *이 범위 내에 있지 않다는 것이 정확히 도움이되지는 않습니다. – fuz

답변

4

는이 같은 단어를 입력 :

여기 내 코드입니까?

[this,is,an,example,sentence] 

구문이 올바르지 않습니다. 당신이 입력에 리터럴 문자열을 원하는 경우에, 당신은 큰 따옴표 (")에서 그것을 encapsulte해야 :

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

을 그 당신의 오류,이 대답을 무시 주시기없는 경우.

+0

구문이 정확하기 때문에 구문 오류가 아니라 "범위 내에 있지 않음"오류가 발생합니다. – Ingo

+1

@Ingo 물론 구문은 형식적으로 정확하지만 OP가 원하는 것은 아닙니다. – fuz

3

코드가 올바르게 작동합니다.

그러나 length을 사용하지 않고 한 번에 목록을 분할하는 것이 좋습니다. 물론 순서는 중요하지 않습니다. 단지 두 개의 동일한 크기 목록 만 가지고 있습니다. ...

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 [] = ([],[]) 
splitList [x] = ([x],[]) 
splitList (x:y:zs) = let (xs,ys) = splitList zs in (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)) 
+0

비슷한 해결책을 제안했을 때 #haskell에서 지적했듯이 절충안이 있습니다.이 솔루션에서는 정렬이 안정적이지 않습니다. –

+0

음, 원래 목록의 길이를 한 번 계산하십시오. 그런 다음 헬퍼에게 보내는 목록의 길이를 전달합니다.이 작업은 2 번의 작업으로 간단하게 나눌 수 있습니다. 개인적으로 원래 목록의 각 요소를 싱글 톤 목록에 매핑하는 방식은 멋지다고 생각합니다. –