功能:构造一个整数列表 1..n
这不是家庭作业。 我正在自学标准机器学习。 我也了解一点Scheme,所以这个问题应该可以用任何一种语言来回答。
我给自己布置的任务是编写一个函数,构造一个从 1 到 n 的整数列表。 例如,list(7) 应返回 [1,2,3,4,5,6,7]。 O(n) 的解决方案将是理想的。
在线性时间内反向构造一个列表(即 [n,n-1,..,1])很容易:
fun list 1 = 1::nil
| list n = n::list(n-1);
我尝试构造一个向前的列表是 O(n^2),因为追加操作是线性的。
fun list 1 = 1::nil
| list n = list(n-1) @ n::nil;
我的下一个尝试是从 nil 开始,将 n 附加到前面,然后向后递归到 1,从尾到前(从右到左)构建一个列表。但它根本不起作用。
fun list n = (if n = 1
then 1
else list(n-1) :: n) :: nil;
有些事情让我觉得我需要一个辅助函数来构建要在递归中使用的未终止列表,但我被难住了。
This is not homework. I'm learning Standard ML on my own. I know a bit of Scheme, too, so this question ought to be answerable in either language.
My self-imposed assignment is to write a function that constructs a list of integers from 1 to n. For example, list(7) should return [1,2,3,4,5,6,7]. An O(n) solution would be ideal.
It's easy to construct a list in reverse (i.e., [n,n-1,..,1]) in linear time:
fun list 1 = 1::nil
| list n = n::list(n-1);
My attempt to construct a list going forward is O(n^2) because the append operation is linear.
fun list 1 = 1::nil
| list n = list(n-1) @ n::nil;
My next attempt was to build a list from the end to the front (right to left) by starting with the nil, attaching n to the front, and recursing backwards to 1. But it didn't work at all.
fun list n = (if n = 1
then 1
else list(n-1) :: n) :: nil;
Something makes me think I need a helper function that builds un-terminated lists to be used in the recursion, but I'm stumped.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 基础库,
通过一个简单的累加器,
这会从尾部开始构建一个列表。 如果您考虑减少,
或者,
未终止列表的表示是一个接受列表并返回列表的函数:例如,要表示
10::_
,您可以使用fn x =>; 10::x
。再次,如果您考虑减少,
在这种情况下,可以对算法进行结构化,使普通数据结构足以满足累加器的要求,但使用延续作为累加器是一种非常强大且有用的技术,不应被忽视。
Using the Basis Library,
With a simple accumulator,
This builds a list starting from the tail end. If you think of the reductions,
Alternatively,
A representation of an unterminated list is a function which takes a list and returns a list: for example, to represent
10::_
, you could usefn x => 10::x
.Once again, if you think of the reductions,
In this case, the algorithm can be structured such that an ordinary data structure suffices for the accumulator, but using a continuation as an accumulator is a very powerful and useful technique that should not be overlooked.
一种经典的方法是以相反的顺序构建它,然后反转它。 这是 O(n) 的两倍,当然也是 O(n)。
One classic approach is to build it in reverse order, then reverse it. That's two times O(n), which is of course just as O(n).
这是一个解决方案:
Here's a solution:
这是使用辅助函数和支持尾递归的累加器的版本:
Here's a version using a helper function and a tail-recursion-enabling accumulator:
对于此类列表问题,解决更普遍的问题通常更容易。
该解决方案具有基本情况和归纳步骤:
If n > m,列表为空。
如果n <= m,解决方案是写n,然后是问题的解决方案n+1 <= i <= m。
这种观点可以快速生成清晰、简洁的 ML 代码(经过测试):
With list problems like these, it is often easier to solve a more general problem.
The solution has a base case and an induction step:
If n > m, the list is empty.
If n <= m, the solution is to write n followed by the solution to the problem n+1 <= i <= m.
This view leads quickly to clear, concise ML code (tested):