计算所有删除了第n个元素的子列表

时间:2019-08-15 12:51:27

标签: haskell

我正在寻找一个函数f,给定一个n元素列表,该函数计算一个n个长度为n-1的子列表。此外,第n个子列表应包含除原始列表的第n个元素以外的所有元素。例如:

f [1..4] == [[2,3,4], [1,3,4], [1,2,4], [1,2,3]]

我找到了一个似乎可行的解决方案,但看起来并不直观:

f :: [a] -> [[a]]
f [] = []
f xs = reverse $ go (length xs - 1) xs
  where
    go 0 _  = [[]]
    go n xs = [ y:ys | y:xs' <- tails xs, ys <- go (n-1) xs' ]

有什么建议可以提供更合理,性能更合理的解决方案?

2 个答案:

答案 0 :(得分:8)

f xs = [ ys ++ zs | (ys, _ : zs) <- zip (inits xs) (tails xs) ]

initstails依次为您提供所有前缀和后缀(请看一下zip (inits xs) (tails xs)的结果)。列表推导从每个非空后缀(_ : zs)中取出一个元素,然后将其余元素串联在一起。

答案 1 :(得分:1)

您可以通过观察作业问题包含一个递归结构来简化很多工作,该递归结构与沿列表本身的递归完全匹配。如果您对输入进行模式匹配且非空,则它具有列表的第一个元素,然后是列表的其余元素。列表的其余部分整齐地对应于没有第一个元素的原始列表,因此它应该是第一个输出。然后是递归-获得其余结果只是将f直接应用到列表的其余部分,然后固定值,使它们的长度正确,并从正确的元素开始。