S4e*_*3sm 2 recursion haskell list lazy-evaluation
我将找到解决这个问题的方法:
将给定列表拆分为具有给定子列表长度和跳过长度的子列表,例如:
groupEvery 3 1 [1..6] = [[1,2,3], [2,3,4], [3,4,5], [4,5,6]]
groupEvery 3 2 "abcdefghij" = [ "abc", "cde", "efg", "ghi", "ij"]
Run Code Online (Sandbox Code Playgroud)
参数groupEvery n p l详细信息是:
这是我的解决方案:
groupEvery :: Int -> Int -> [a] -> [[a]] -> [[a]]
groupEvery n p xs acc
| length xs <= n = acc ++ [xs]
| otherwise = groupEvery n p dropped (acc++[segment])
where
dropped = drop p xs
segment = take n xs
Run Code Online (Sandbox Code Playgroud)
但这个解决方案并不懒惰,例如take 3 Lib2.groupEvery 3 1 [1..] []从未完成。我的问题是关于
groupEvery功能有更好的解决方案吗?主要问题是您使用累加器并且仅在遍历整个输入列表时才返回列表。此外,length l还将浏览整个列表。您不需要计算长度。这也是低效的:如果列表很长,它每次都会进行线性运行。
您可以在列表上进行模式匹配,对于空列表返回一个空列表,对于非空列表产生take n xs并使用 递归drop p xs。
groupEvery :: Int -> Int -> [a] -> [[a]]
groupEvery _ _ [] = []
groupEvery n p xs = take n xs : groupEvery n p (drop p xs)
Run Code Online (Sandbox Code Playgroud)
由此产生:
ghci> take 3 (groupEvery 3 1 [1..])
[[1,2,3],[2,3,4],[3,4,5]]
Run Code Online (Sandbox Code Playgroud)
take n您可以通过组合和来进一步改进该功能drop p,这样您只需遍历min n p列表的各个部分一次。我把它留作练习。
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |