Haskell:将偶数和奇数元素分成元组

时间:2010-09-14 09:47:05

标签: haskell

我无法使用高阶函数。我只是无法弄清楚如何做到这一点。我对哈斯克尔很新。它也必须是递归的。

split :: [Int] -> ([Int],[Int])
split xs = 

我从一开始就给予了这个。老实说,我甚至不知道从哪里开始这个问题。

示例:

split []
([],[])

split [1]
([1],[])

split [1,2,3,4,5,6,7,8,9,10]
([1,3,5,7,9],[2,4,6,8,10])

任何帮助都会非常感激。

编辑:它的偶数和奇数位置。

所以

分裂[3,6,8,9,10]将是 ([3,8,10],[6,9])

好的,所以我想出了这个。它不漂亮,但似乎工作正常。

split :: [Int] -> ([Int],[Int])
split [] = ([],[])
split [xs] = ([xs],[])
split xs = (oddlist xs, evenlist xs)

oddlist :: [Int] -> ([Int])
oddlist xs | length xs <= 2 = [head(xs)]
           | otherwise = [head(xs)] ++ oddlist(tail(tail(xs)))

evenlist :: [Int] -> ([Int])
evenlist xs | length xs <= 3 = [head(tail(xs))]
            | otherwise = [head(tail(xs))] ++ evenlist(tail(tail(xs)))

5 个答案:

答案 0 :(得分:17)

split [] = ([], [])
split [x] = ([x], [])
split (x:y:xs) = (x:xp, y:yp) where (xp, yp) = split xs

答案 1 :(得分:5)

如果你放松了&#34;没有更高阶的功能&#34;限制,你可以这样做:

split :: [a] -> ([a],[a])
split = foldr (\x ~(y2,y1) -> (x:y1, y2)) ([],[])

注意~使模式匹配延迟,因此split可以按需生成结果,而不是首先检查整个列表。

您可以通过展开foldr

重新实施限制
split :: [a] -> ([a],[a])
split [] = ([],[])
split (x : xs) = (x : y1, y2)
  where
    (y2, y1) = split xs

答案 2 :(得分:3)

如果不允许使用高阶列表函数,则替代方法基本上是使用递归。

示例已经提供了您需要满足的案例:

-- Base case:
split [] = …

-- Recurrence:
split (x : xs) = (do something with x) … (split xs) …

答案 3 :(得分:2)

既然你现在已经提出了解决方案,我就是这样做的:

split xs = (everyother 0 xs, everyother 1 xs)
      where everyother _ []     = []
            everyother 1 (x:xs) = everyother 0 xs
            everyother 0 (x:xs) = x : (everyother 1 xs)

这意味着列表中的第一项是第0项。

答案 4 :(得分:1)

我认为这与Get every Nth element有关。

无论如何,这就是我要做的事情:

ghci> let split ys = let skip xs = case xs of { [] -> [] ; [x] -> [x] ; (x:_:xs') -> x : skip xs' } in (skip ys, skip . drop 1 $ ys)
ghci> split [1..10]
([1,3,5,7,9],[2,4,6,8,10])

或格式很好:

split xs = (skip xs, skip . drop 1 $ xs)
  where 
  skip [] = []
  skip [x] = [x]
  skip (x:_:xs') = x : skip xs'