【问题标题】:contiguous sublists from an ascending sequence升序中的连续子列表
【发布时间】:2013-01-09 12:58:27
【问题描述】:

给定

xs = [1,2,3,4,6,7,9,10,11]

我的目标是返回

[[1,2,3,4],[6,7],[9,10,11]]

我认为我可以做到:

groupBy (\x y -> succ x == y) xs

但这会返回:

[[1,2],[3,4],[6,7],[9,10],[11]]

一点点搜索从 Haskell Data.List 建议 page 中返回以下内容。

groupBy                 :: (a -> a -> Bool) -> [a] -> [[a]]
 groupBy rel []          =  []
 groupBy rel (x:xs)      =  (x:ys) : groupBy rel zs
   where (ys,zs) = groupByAux x xs
         groupByAux x0 (x:xs) | rel x0 x = (x:ys, zs)
           where (ys,zs) = groupByAux x xs
         groupByAux y xs = ([], xs)

他们给出的一个例子正是我想要的:

groupBy (\a b -> a+1 == b) [1,2,3,4,6]
[[1,2,3,4],[6]]

所以我的问题......有没有另一种方法来解决这个问题,而不是重新定义groupBy,因为它看起来有点戏剧化?

编辑...

我决定按如下方式实现:

pattern :: (Enum a, Eq a) => (a -> a) -> [a] -> [[a]]
pattern f = foldr g []
  where g a [] = [[a]]
        g a xs | f a == head (head xs) = (a : head xs): tail xs
               | otherwise = [a]:xs

允许这样的事情:

*Main Map> pattern succ "thisabcdeisxyz"
["t","hi","s","abcde","i","s","xyz"]
*Main Map> pattern (+ 3) [3,6,9,12,1,2,3,2,5,8,23,24,25]
[[3,6,9,12],[1],[2],[3],[2,5,8],[23],[24],[25]]

或者完全像 group 一样运作——并不是没有任何理由:

*Main Map> let xs = [1,1,1,2,3,4,5,6,6,6,5]
*Main Map> group xs == pattern id xs
True

【问题讨论】:

    标签: list haskell sequence


    【解决方案1】:

    有很多方法可以做到这一点。一种方法是使用 foldr

    f = foldr g []
      where g a [] = [[a]]
            g a xs@(x:xs') | a+1 == head x = (a : x): xs'
                           | otherwise = [a]:xs
    

    现在尝试一下

    *Main> f [1,2,3,4,6,7,9,10,11]
    [[1,2,3,4],[6,7],[9,10,11]]
    

    【讨论】:

    • 您可以/应该在g 中的xs 上进行模式匹配,即g a xs@(x:xs') 并使用 xxs' 代替 head 和 tail 调用。
    • @dbaupp 我以前做过,但一直到第二级,这使得代码非常不可读。最好只使用一个级别。
    【解决方案2】:

    如果xs 严格增加则

     myGrouping = map (map snd) . groupBy (\(u, v) (x, y) -> u - v == x - y) . zip [0..]
    

    解决你的问题。

    Prelude> myGrouping [1,2,3,4,6,7,9,10,11]
    [[1,2,3,4],[6,7],[9,10,11]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 2011-06-29
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多