【问题标题】:Haskell how to drop all 0 of the list until one of the elements /= 0?Haskell如何删除列表中的所有0直到元素之一/ = 0?
【发布时间】:2021-04-15 02:06:28
【问题描述】:

我是 Haskell 的新手,我正在尝试弄清楚如何编写代码,该代码会删除所有零,直到列表中的元素 >0。

例如:

输入:[0,0,5,6,0]

输出:[5,6,0]

到目前为止,我已经写了这个:

zeroUntil :: [Int] -> [Int]
zeroUntil [] = []
zeroUntil (x:xs)
    | x == 0 = drop x (xs)
    | otherwise = zeroUntil xs

但不知何故,我得到了 [5,6,0],而不是 []。

谁能解释一下我做错了什么?

【问题讨论】:

  • 您的实现与您的输出不匹配。在您描述的输入上运行时,它不会给出[],而是给出[0,5,6,0]。当然,仍然是错误的:它实现的功能与您的预期完全不同。但是请通过粘贴您的实际代码和输出并在发布前仔细检查它们来确保您的问题是可重现的。

标签: list haskell recursion guard


【解决方案1】:
zeroUntil :: [Int] -> [Int]
zeroUntil [] = []
zeroUntil (x:xs)
    | x == 0 = drop x (xs)
    | otherwise = [x] ++ (zeroUntil xs)

您必须将第一个元素 (x) 添加到递归调用返回的列表中,否则您将返回一个空列表。

【讨论】:

    【解决方案2】:

    您可以使用dropWhile :: (a -> Bool) -> [a] -> [a] 并因此丢弃项目,只要它们是零:

    zeroUntil :: [Int] -> [Int]
    zeroUntil = dropWhile (0 ==)

    如果你想删除零直到一个元素大于零,你可以使用递归。如果这些元素小于零,你的递归案例应该产生元素:

    zeroUntil :: [Int] -> [Int]
    zeroUntil [] = []
    zeroUntil (0:xs) = zeroUntil xs
    zeroUntil (x:xs)
        | x > 0 = x : xs  -- ← end of recursion, return the list
        | otherwise = x : zeroUntil xs  -- ← yield x and recurse

    例如:

    Prelude> zeroUntil [0,0,5,6,0]
    [5,6,0]
    Prelude> zeroUntil [0,-1,5,6,0]
    [-1,5,6,0]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-28
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      • 2022-07-11
      • 2013-10-02
      相关资源
      最近更新 更多