【发布时间】:2012-08-05 22:02:21
【问题描述】:
我有一个旋转列表的功能:
rotate :: [a] -> [a]
rotate [] = []
rotate (x:xs) = xs ++ [x]
现在我想要一个函数,它给出一个有限列表的每个可能旋转的列表:
rotateAll :: [a] -> [[a]]
在命令式语言中,我会做类似(在伪代码中)
for i = 1 to length of list
append list to rotateList
list = rotate(list)
当然,命令式思考可能无法帮助我找到解决这个问题的有效方法。我正在寻找一些关于如何解决这个问题的提示。
其他想法:
为了解决这个问题,我有两个问题要解决。首先,我需要反复轮换一个列表并将每个结果收集到一个列表中。所以第一个解决方案需要做类似的事情
rotateAll xs = [xs (rotate xs) (rotate (rotate xs)) (rotate (rotate (rotate xs))) ...]
当然,我不知道要这样做多少次。我很乐意无限地执行此操作,然后使用take (length xs) 来获得我想要的有限数量的列表。这实际上说明了第二个问题:确定何时停止。我不知道使用 take 是否是解决问题的最有效或最优雅的方法,但在我输入此内容时我想到了它并且应该可以工作。
附录: 现在我已经找到了两种解决方案,或者有提示。我很乐意欢迎任何其他更快或使用不同方法的解决方案。谢谢!
【问题讨论】:
-
看看
iterate函数。 -
@TiloWiklund 这正是我想要的。谢谢!
-
请注意,您将在每次迭代中遍历列表一次(追加为 O(n),对于 n 列表的长度)和一次用于计算
xs的长度(即也是 O(n)) -
有趣的是,您也可以为无限输入列表解决此问题 - 只要您旋转正确的方向。提出一个适用于无限和有限输入的解决方案是一个很好的进一步练习。
-
@TiloWiklund 我通常想先制定一个可行的解决方案,然后再进行调整以提高效率。在最初的解决方案中牢记这些问题仍然是件好事。所以感谢您指出!如果以后有问题,我会重新访问我的
rotate函数。
标签: list haskell functional-programming