Ocaml:两个整数的函数,返回范围内所有整数的列表

时间:2011-08-28 06:43:14

标签: 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”。有人可以说明为什么我会收到这个错误吗?

感谢。

3 个答案:

答案 0 :(得分:7)

它应该是这样的:

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;;

我做了什么:

  1. loop更改为range_rec
  2. (l@[a], a+1, b)更改为(l @ [a]) (a + 1) b。第一个是三元组,第二个是curried函数的3个参数。
  3. 请注意,if (a = b) then可以写为if a = b then
  4. 最后,通过循环“向后”,使用::代替@可以提高功能效率。例如,像gasche所示。

答案 1 :(得分:6)

从性能角度来看,l @ [elem]操作非常糟糕:由于a @ ba的长度上是线性的,因此在列表末尾添加元素的长度是线性的。列表,使您的整个range_rec定义在|b-a|中呈二次方式。要做的就是更改代码,以便您可以使用常量elem::l操作。

let rec range a b =
  if a > b then []
  else a :: range (a + 1) b

您可以进行其他优化,例如使其尾递归,但至少此解决方案的复杂性是正确的。

答案 2 :(得分:1)

为了改进gasche已经提出的解决方案,可以将其设置为尾递归。

let int_range a b =
  let rec int_range_rec l a b =
    if a > b then l
    else int_range_rec (b :: l) a (b - 1)
  in (int_range_rec [] a b);;