Ocaml:函数计算两个整数并返回范围内所有整数的列表
该函数接受两个整数并返回 [a,b] 范围内所有整数的列表,
这是我编写的解决方案。
let rec range_rec l a b =
if (a=b) then l@[b]
else range_rec (l@[a], a+1, b);;
let range a b = range_rec [] a b;;
我遇到错误“错误:此表达式的类型为 int list * int * int,但表达式应为 int 类型”。有人可以解释一下为什么我会收到此错误吗?
谢谢。
This function takes two integers and returns the list of all integers in the range [a,b]
This is the solution that I wrote.
let rec range_rec l a b =
if (a=b) then l@[b]
else range_rec (l@[a], a+1, b);;
let range a b = range_rec [] a b;;
I'm hitting an error "Error: This expression has type int list * int * int but an expression was expected of type int". Can someone throw some light on why am I getting this error?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它应该看起来像这样:
我所做的:
loop
更改为range_rec
(l@[a], a+1, b)
到(l @ [a]) (a + 1) b
。第一个是三元组,第二个是柯里化函数的 3 个参数。if (a = b) then
可以写为if a = b then
。最后,通过“向后”循环使用
::
而不是@
可以使该函数更加高效。例如,像加斯切(gasche)所展示的那样。It should look like this:
What I've done:
loop
torange_rec
(l@[a], a+1, b)
to(l @ [a]) (a + 1) b
. The first is a triplet and the second is 3 arguments to a curried function.if (a = b) then
can be written asif a = b then
.Last, the function can be made more efficient by using
::
instead of@
by looping "backwards". For example like gasche have shown.从性能角度来看,
l @ [elem]
操作非常糟糕:因为a @ b
与a
的长度呈线性关系,因此添加一个元素到列表末尾与列表长度呈线性关系,使整个range_rec
定义在|ba|
中呈二次方关系。解决方法是更改代码,以便可以使用恒定时间elem::l
操作。您可以进行其他优化,例如使其成为尾递归,但至少该解决方案的复杂性是正确的。
The
l @ [elem]
operation is terrible from a performance perspective : asa @ b
is linear in the length ofa
, adding an element to the end of list is linear in the length of the list, making your wholerange_rec
definition quadratic in|b-a|
. The way to go is to change your code so that you can use the constant-timeelem::l
operation instead.You may make additional optimizations such as making it tail-recursive, but at least the complexity of this solution is right.
为了改进gasche已经建议的解决方案,可以将其设为尾递归。
To improve on the solution already suggested by gasche, this can be made tail-recursive.