ここでは別のアプローチがあります。今のところ、あなたの例のように、リストに隣接する等しい要素がないとしましょう。リストlst
が独自のテールと比較される場合、要素ごとの:
> let lst = [1,2,31,23,22,1,43]
> let dir = zipWith compare lst (tail lst)
> dir
[LT,LT,GT,GT,GT,LT]
次いでdir
は、隣接する要素が増加または減少しているかどうかを表します。私たちは、このリストの先頭を繰り返していた場合:
> let dir' = head dir : dir
> dir'
[LT,LT,LT,GT,GT,GT,LT]
はその後dir'
リスト[1,2,31,23,22,1,43]
をグループ化する方法に対応しています。dir'
要素によってlst
とグループ化してdir'
をビュンによって、我々が得る:我々はフィルタリングでき
> import Data.Function -- for `on`
> let groups = groupBy ((==) `on` fst) (zip dir' lst)
> groups
[[(LT,1),(LT,2),(LT,31)],[(GT,23),(GT,22),(GT,1)],[(LT,43)]]
:すべて一緒にこれを入れて、だから、
を、我々はより高次の解を得ます:
groupIncDec' :: Ord a => [a] -> [[a]]
groupIncDec' lst =
let dir = zipWith compare lst (tail lst)
in map (map snd)
$ groupBy ((==) `on` fst)
$ zip (head dir : dir) lst
これは、隣接する重複した要素を持つリストに正しく動作しませんが、我々はそのようなリストを取ることができます:
lst' = [1,2,31,31,23,22,22,1,43]
とグループそれ:
group lst' = [[1],[2],[31,31],[23],[22,22],[1],[43]]
、その後、効果的に、最終的な結果を得るために、再びそれを「グループ解除」の前に、上記のアルゴリズムを適用します。それは次のようになります。
> groupIncDec [1,2,31,23,22,1,43]
[[1,2,31],[23,22,1],[43]]
> groupIncDec [1,2,31,31,23,22,22,1,43]
[[1,2,31,31],[23,22,22,1],[43]]
は、その機能が正確に何をしない:
そうのように動作しますか?私はその例だけでは分かりません。 – AJFarmar
は、 'groupIncDec'のように' '[[a]]、(a)) - >([[a]]、[a])の関数をラップすることができます。 'x'が' ']のときは、' 'x''が反対方向に向いていて、' 'xs''が' '' 'になっています。 –
'groupBy'はメモリを持たないので使用できません。一度に2つの隣接する要素しか見ることができません。 –