0

[1,2,4,5,6,7]手動で に分割するにはどうすればよい[[1],[2],[3],[4],[5],[6],[7]]ですか? 手動とは、ブレークを使用しないことを意味します。

では、述語に従ってリストをサブリストに分割するにはどうすればよいでしょうか。そのようです

f even [[1],[2],[3],[4],[5],[6],[7]] == [[1],[2,3],[4,5],[6,7]]

PS: これは宿題ではありません。私は何時間もかけて自分で解決しようとしました。

4

3 に答える 3

3

最初の質問に答えると、これは分割ではなく要素ごとの変換です。これを行う適切な関数は次のとおりです。

map :: (a -> b) -> [a] -> [b]

ここで、要素を同じ型を含むシングルトン リストに変換するため、関数(a -> b)where bis が必要です。[a]ここにあります:

mkList :: a -> [a]
mkList a = [a]

それで

map mkList [1,2,3,4,5,6,7] == [[1],[2],...]

2 番目の質問について: の使用が許可されていない場合 (宿題ですか?) 、 の結果の両方の半分を形成するとbreakを使用することは許可されていますか?takeWhiledropWhilebreak

とにかく、それらを使わずに (「手動で」) 解決するには、アキュムレータを使用して単純な再帰を使用するだけです。

f p [] = []
f p (x:xs) = go [x] xs
    where go acc [] = [acc]
          go acc (y:ys) | p y = acc : go [y] ys
                        | otherwise = go (acc++[y]) ys

これにより、現在のサブリストが何であるかを常に記憶し、リストの末尾全体を再帰的に走査し、p適用される要素に到達すると、現在のサブリストを出力して新しいサブリストを開始します。

最初の要素がすでに満たされ、空の最初のサブリストを出力したくない場合を提供する[x]代わりに、 go first が受け取ることに注意してください。[]p x

[1..7]また、これは の代わりに元のリスト ( ) で動作し[[1],[2]...]ます。ただし、変換されたものでも使用できます。

> map concat $ f (odd . head) [[1],[2],[3],[4],[5],[6],[7]]
[[1,2],[3,4],[5,6],[7]]
于 2013-08-01T11:15:32.650 に答える
2

まず、リスト内包表記を使用できます。

>>> [[x] | x <- [1,2,3,4,5,6]]
[[1], [2], [3], [4], [5], [6]]

2 番目の問題については、パッケージによって提供されるData.List.Splitモジュールを使用できます。split

import Data.List.Split

f :: (a -> Bool) -> [[a]] -> [[a]]
f predicate = split (keepDelimsL $ whenElt predicate) . concat

の関数はリストのリストではなくリストで機能するため、この最初のconcatはリストを連結します。split結果の単一リストは、分割パッケージの関数を使用して再度分割されます。

于 2013-08-01T11:28:29.390 に答える