【问题标题】:Return a list, which contains a pair of elements, but only if the respective elements' sums are odd返回一个列表,其中包含一对元素,但前提是各个元素的总和为奇数
【发布时间】:2021-12-09 07:29:59
【问题描述】:

实现返回对列表的oddPairs :: [Int] -> [Int] -> [(Int, Int)] 函数,但前提是参数列表各自元素的总和为奇数。

例如:

oddPairs [1,2,3] [2,2,2] == [(1,2),(3,2)]

oddPairs [1,3,5] [2,4,6] == zip [1,3,5] [2,4,6]

oddPairs [1,2,3] [1,2,3] == []

到目前为止,我已经尝试过

oddPairs (x:xs) (y:ys) | (x+y) `mod` 2 == 0 = []
                       | (x+y) `mod` 2 /= 0 = [(x, y)] ++ oddPairs (xs) (ys)

在第一个示例中,它仅返回 [(1,2)],在第二个示例中,它返回正确的值,但出现 Non-exhaustive patterns 错误。

【问题讨论】:

  • 顺便说一下,Prelude 包括even :: Integral a => a -> Bool,使用mod(==) 实现,正如您在此处所做的那样。

标签: haskell recursion modulo


【解决方案1】:

很简单的列表理解:

oddPairs :: [Int] -> [Int] -> [(Int, Int)]
oddPairs ms ns = [(m, n) | (m, n) <- zip ms ns, odd (m + n)]

确实:

> oddPairs [1, 2, 3] [2, 2, 2] == [(1, 2),(3, 2)]
True
> oddPairs [1, 3, 5] [2, 4, 6] == zip [1, 3, 5] [2, 4, 6]
True
> oddPairs [1, 2, 3] [1, 2, 3] == []
True

【讨论】:

    【解决方案2】:

    另一种看待问题的方法是,您只需要具有奇数和的。这是强调的细微差别,可能会导致以下情况。

    使用zip 函数将每个列表组合成。然后使用filter 找到奇数的。

    oddPairs :: Integral a => [a] -> [a] -> [(a, a)]
    oddPairs f s = filter oddPair (zip f s)
        where oddPair (l, r) = not $ even (l + r)
    

    【讨论】:

      【解决方案3】:

      如果两个项目是偶数,你不应该只返回一个空列表,而是继续递归,直到至少有一个列表被用完,所以:

      oddPairs :: Integral a => [a] -> [a] -> [(a, a)]
      oddPairs [] _ = []
      oddPairs _ [] = []
      oddPairs (x:xs) (y:ys)
          -- keep searching for new items &downarrow;
          | (x+y) `mod` 2 == 0 = oddPairs xs ys
          | otherwise = (x, y) : oddPairs xs ys

      【讨论】:

      • 哇,你真快:D
      猜你喜欢
      • 1970-01-01
      • 2020-04-19
      • 2020-11-22
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 2013-11-26
      相关资源
      最近更新 更多