【问题标题】:Divide the list into sub-lists: the same values are added to one sublist and different values are added to another将列表划分为子列表:将相同的值添加到一个子列表中,将不同的值添加到另一个子列表中
【发布时间】:2022-01-04 01:08:12
【问题描述】:

将列表划分为子列表:将相同的值添加到一个子列表中,将不同的值添加到另一个子列表中。它需要使用foldr 通过列表的一轮完成,而不使用++

例如:

ghci> splitList [1,2,2,4,5,7,7,8,9] 

[[1],[2,2],[4,5],[7,7],[8,9]]

我做了类似的事情:

splitList :: [Int] -> [[Int]]
splitList = getRes . foldr func5 ([],False,0) where
  func5 c ([],_,_) = ([[c]],False,c)
  func5 c (y@(x:xs), b, l) | c == l = ((c:x):xs, False, c)
                           | b = ((c:x):xs, False, c)
                           | otherwise = ([c]:y, True, c)

getRes :: ([[Int]], Bool, Int) -> [[Int]]
getRes (a,_,_) = a

但它并没有像我预期的那样工作......

ghci> splitList [1,2,2,4,5,7,7,8,9]

[[1],[2,2],[4,5],[7,7,8],[9]]

【问题讨论】:

    标签: list haskell fold


    【解决方案1】:

    由于您使用的是foldr

    > splitList [1,2,2,4,5,7,7,8,9]
    
    [[1],[2,2],[4,5],[7,7],[8,9]]
    

    应该像右边一样工作

    > splitList [1,2,2,4,5,7,7,8,9]
                                  []
                               [[9]]
                             [[8,9]]
                           [[7,8,9]]
                         [[7,7],[8,9]]
                       [[5],[7,7],[8,9]]
                     [[4,5],[7,7],[8,9]]
                   [[2,4,5],[7,7],[8,9]]
                 [[2,2],[4,5],[7,7],[8,9]]
               [[1],[2,2],[4,5],[7,7],[8,9]]
    

    现在剩下的就是用代码写下来。

    从上面可以看出,我们只需要将当前元素与“累加器”的头部进行比较(除了特殊情况下无条件收集的列表的最后两个元素),同时保持“相同”标志。所以可以编码为

    splitList :: Eq a => [a] -> [[a]]
    splitList xs = snd $ foldr g (undefined,[]) xs
      where
      g x (b,[]) = (b,[[x]])
      g x (_,[y]:t) = (x==y,[x,y]:t)
      g x (b,(a:r):t)
         | (x==a)==b  = (b,(x:a:r):t)
         | otherwise  = (not b, if b then [x]:(a:r):t
                                     else [x,a]:r:t)
    

    测试:

    > splitList [1,2,2,4,5,7,7,8,9]
    [[1],[2,2],[4,5],[7,7],[8,9]]
    
    > splitList [1,2,2,4,5,7,7,8,9,9]
    [[1],[2,2],[4,5],[7,7],[8],[9,9]]
    
    > splitList [1,2,2,4,5,7,8,9,9,9]
    [[1],[2,2],[4,5,7,8],[9,9,9]]
    

    【讨论】:

    • 你真的不需要标志godbolt.org/z/roErEW6xG
    • @n.1.8e9-where's-my-sharem。是的,我可以比较 head 子组中的前两个元素来恢复它,但我想避免重复比较。
    猜你喜欢
    • 1970-01-01
    • 2013-03-25
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 2021-08-18
    • 2018-03-06
    相关资源
    最近更新 更多