Haskell:将偶数和奇数元素拆分为元组
我不能使用高阶函数。我只是不知道该怎么做。我对哈斯克尔很陌生。它还必须是递归的Haskell:将偶数和奇数元素拆分为元组,haskell,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,
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)))
split::[Int]->([Int],[Int])
拆分[]=([],[])
拆分[xs]=([xs],])
拆分xs=(oddlist xs,evenlist xs)
oddlist::[Int]->([Int])
oddlist xs |长度xs([Int])
evenlistxs | length xs如果不允许使用高阶列表函数,那么基本上可以使用递归
示例已经给出了您需要满足的情况:
-- Base case:
split [] = …
-- Recurrence:
split (x : xs) = (do something with x) … (split xs) …
既然您现在提出了解决方案,我将这样实施:
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。我认为它与
不管怎样,这就是我要做的:
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'
如果您放宽“无高阶函数”限制,您可以这样做:
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
你的签名有点不对劲…@Konrad:我不知道你的意思。这两个?
是不一样的,我忽略了两个基本情况。算了吧……我显然与Haskell失去联系太久了。请看我的原始答案:列表构造函数缺少括号。@Konrad:对,使用单个参数的函数永远不会出现;-)你的例子有点模棱两可,你是指偶数和奇数位置的元素,还是指本身是偶数或奇数的整数?一个更好的例子可能是:split[1,3,2,5,8]
~>([1,3,5],[2,8])
哦,是的,对不起,元素位于偶数和奇数位置。@Tom嘿,谢谢。没有注意到。请注意,@Kenny's和我的解决方案解决了不同的问题。正如@Tom在你的问题下面所评论的,由于你的例子模棱两可,所以不清楚这两个解决方案中哪一个适合你的问题。是的,这很好。有趣的想法。我修复了交换的结果,并以预期的方式使事情变得懒惰。
split :: [a] -> ([a],[a])
split [] = ([],[])
split (x : xs) = (x : y1, y2)
where
(y2, y1) = split xs