我被指派编写一段Haskell代码,该代码生成一个无限列表,其中包含越来越多的'a's。
我的第一个想法是把它写成这样的清单理解:
aStar = [replicate n 'a' | n <- [0..]]
但是当我问我的教授时,他说我应该使用显式递归,所以我想出了这样的方法:
aStar :: [String]
--repeats a string from 0
aStar = repeat' 0 'a'
repeat' :: Int -> Char -> [String]
repeat' n x = [cycle' x n] ++ repeat' (n + 1) x
where cycle' _ 0 = ""
cycle' y z = [y] ++ cycle' y (z - 1)
有更短的方法吗?
发布于 2015-08-30 00:25:21
这两种解决方案都存在效率问题,但至少您最初的列表理解具有简短和可读性的优点。你修改后的解决方案可以说更糟。
replicate
的问题是每个字符串都是从头开始重建的。
第二个解决方案的问题是,您使用的是++
,它附加到列表的末尾。这需要遍历到列表的末尾,随着列表越来越长,这将变得越来越耗时。无论何时编写++
,都应该努力找到一种更好的方法。
这是您的教授可能想到的解决方案(注意使用:
而不是++
):
aStar :: [String]
aStar = aStar' 'a' ""
where
aStar' c s = s : aStar' c (c : s)
发布于 2015-08-30 04:04:21
另一种方法是:
aStar = iterate ('a':) ""
https://codereview.stackexchange.com/questions/102262
复制相似问题