2010-11-17 10 views
7

リスト[1,2,4,1,5,7,3,4,2,3]を分割する値に分割されるサブリストのリストにどのように分割できますかシーケンス。例えば、リスト[1,2,4,1,5,7,3,4,2,3]は、[[1,2,4]、[1,5,7]、[ 3,4]、[2,3]]。リストをソートされたサブリストに分割する

この問題や解決方法に関するご意見は、この問題を解決する方法を教えてください。

ありがとうございました。

+0

おかげさまで多くの人に感謝します。あなたは本当に助けになりました。良い情報がたくさんありました:) –

+0

宿題は宿題としてマークしてください。 – luqui

答えて

4

ここにヒントがあります:あなたがリストを処理している間に連続した要素を見るために必要があるとき、それはその尾に対してリストをビュンによって開始することをお勧めします:

Prelude> let f xs = zip xs $ tail xs 
Prelude> f [1,2,4,1,5,7,3,4,2,3] 
[(1,2),(2,4),(4,1),(1,5),(5,7),(7,3),(3,4),(4,2),(2,3)] 

今、あなたは(splitWhen $ uncurry (>)ようなものを使用することができますが、 splitWhenData.List.Split)リストを適切に分割します。

2

2つの関数、最初の項目が2番目の項目よりも小さいときに頭を分割する関数、もう1つは頭を分割する関数の出力を受け取り、再帰呼び出しの結果を連結する関数リスト自体の末尾に上記トラヴィスのよう

splitList :: [Int] -> [[Int]] 
splitList [] = [] 
splitList (x:xs) = ys : splitList zs 
    where (ys,zs) = splitHead (x:xs) 


splitHead :: [Int] -> ([Int], [Int]) 
splitHead [x] = ([x], []) 
splitHead (x:y:xs) 
    | x > y = ([x], (y:xs)) 
    | x <= y = (x:ys, zs) 
    where (ys,zs) = splitHead (y:xs) 
+0

downvoteの理由をお願いします。私はWinHugsで自分のソリューションをテストし、魅力的に働いています。それは非効率的ですか? – Fede

9

、私の最初に考えたのは、自身の尾でリストを圧縮することです: それは非常にこのような状況で働くようにしかし、それは見ていません。あなたが望むだけの機能を実際には果たしていないだけでなく、最初から最後まで要素を失うという問題もあります。適切に抽象化ソリューションの代わりに、これを見てみましょう:

splitAscending :: Ord a => [a] -> [[a]] 
splitAscending = foldr f [] where 
    f x [] = [[x]] 
    f x (y:ys) = if x < head y 
    -- It's okay to call head here because the list y is 
    -- coming from the summary value of the fold, which is [[a]]. 
    -- While the sum value may be empty itself (above case), it will 
    -- never CONTAIN an empty list. In general be VERY CAREFUL when 
    -- calling head. 
     then (x:y):ys -- prepend x to the first list in the summary value 
     else [x]:y:ys -- prepend the new list [x] to the summary value 

迅速かつ汚いソリューション、私はそれが

ニーズに合っを願って - また、これは、スタックオーバーフローの私の最初の投稿です。 )

+0

私はこの解決策が好きで、おそらく私のものよりも単純かもしれないと思っていますが、テールジップアプローチでこれを実装することも可能です*(マップ(\ ys-> fst ys):map snd ys) '' splitWhen'の後に)。 –

2

まあ、これは私が望むほど清潔ではありませんが、ここにあります。 を分割パッケージの使用:括弧は非常に可能性がここにクリーンアップすることができhttp://hackage.haskell.org/package/split

:m+ Data.List.Split 
Prelude Data.List.Split> let f ys = let ys' = zip ys (tail ys) in map (map fst) ((split . whenElt) (uncurry (>)) $ ys') 

を。

1

どの程度

asc [] = [[]] 
asc (x:xs) = map reverse $ reverse $ foldl ins [[x]] xs 
    where ins ((y:ys):yss) z | z > y = (z:y:ys) : yss 
          | otherwise = [z] : (y:ys) : yss 

または

asc = map reverse.reverse.foldl ins [[]] 
     where ins [[]] z = [[z]] 
      ins ((y:ys):yss) z | z > y = (z:y:ys) : yss 
           | otherwise = [z] : (y:ys) : yss  

関連する問題