将列表拆分为已排序的子列表

pac*_*an. 6 haskell functional-programming

如何将列表[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].

有关此的任何想法或建议如何解决此问题?

谢谢.

Jon*_*han 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
Run Code Online (Sandbox Code Playgroud)

一个快速而肮脏的解决方案,我希望它符合您的需求

- 另外,这是我在Stack Overflow上的第一篇文章:)


Tra*_*own 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)]
Run Code Online (Sandbox Code Playgroud)

现在您可以使用类似splitWhen $ uncurry (>)(where splitWhenis from Data.List.Split) 的内容来适当地划分列表。