微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

OCaml:带有 int 列表的 pell 函数

如何解决OCaml:带有 int 列表的 pell 函数

我正在尝试在 OCaml 中编写一个简单的函数

let rec pell (i: int) =
(if i <= 2 then i (*if given n is less tahn 2 then return 2,else return prevIoUs n-1 th term and n-2 nd term recursively*)
  else if i>2 then
  2 * pell i - 1 + pell i - 2

else failwith "unimplemented" (*else fail with unimplemented message*)
);;

编写一个无限精度版本的之前的pell函数

pell2 0 = []

pell2 1 = [1]

pell2 7 = [9; 6; 1]

pell2 50 = [2; 2; 5; 3; 5; 1; 4; 2; 9; 2; 4; 6; 2; 5; 7; 6; 6; 8; 4]

我为此编写了以下代码

let rec pell2 i =

(if i <= 2 then
  [] -> i;
  else if i=0 then [];
  else if i>2 then                                (*finding pell number and using sum function to 
output list with infinite precision...*)
  [] -> pell2 i-1 + pell2 i-2;

else failwith "unimplemented"

);;

但仍有一些语法错误。有人可以帮我解决这个问题吗。

解决方法

if i <= 2 then
     [] -> i

在这样的片段中,-> 无效。看起来您可能将模式匹配与 match ... with ... 和 if/else up 混合使用。

此外,您首先要检查 i 是否小于或等于 2,然后您有一个 else 来测试 i 是否等于 0。第一次检查意味着第二次永远不会发生。

,

首先,让我们看一下 pell2 的输出示例。我们看到 pell2 有一个整数参数,并返回一个整数列表。因此,我们知道我们要创建的函数具有以下类型签名:

pell2: int -> int list

修复(部分但不是全部)语法错误并尝试维护您的逻辑,

let rec pell2 i =
  if i=0 then []
  else if i <= 2 then i
  else if i>2 then pell2 i-1 + pell2 i-2

请注意,我删除了每个表达式末尾的分号,因为 OCaml 在其语法中使用分号专门用于处理计算为单位 () 的表达式。参见 ivg 的优秀explanation on this。这段代码的主要缺陷是它没有类型检查。我们看到我们有条件地返回一个列表,否则返回一个 int。注意上面我们如何定义 pell2 应该返回一个 int list。因此,我们可以通过将 int 结果包装在一个列表中来开始解决这个问题:

let rec pell2 n = 
  if n = 0 then []
  else if n <= 2 then [n]
  else ... something that will return the Pell number as a list ...

正如您已经写的那样,可以使用对 pell2 函数的递归调用来编写 else 分支。但是,我们不能像您之前那样编写它,因为 pell2 计算结果为列表,而二元运算符 + 仅适用于两个整数。因此,我们将不得不定义我们自己的汇总列表的方式。调用此 sum_lists,我们留下以下代码: 我们现在可以完全定义我们的函数 pell2:

let rec pell2 n =
  if n = 0 then []
  else if n <= 2 then [n]
  else (* Pell(n) = (2 * Pell(n-1)) + Pell(n-2) *)
    let half_of_first_term = pell2 n-1 in
    let first_term = sum_lists half_of_first_term half_of_first_term in
    let second_term = pell2 n-2 in
    sum_lists first_term second_term

所以,剩下的就是定义sum_lists,以便我们正确地将两个格式与pell2的返回类型相同的列表相加。 sum_lists 的签名是

sum_lists: int list -> int list -> int list

我将给出实现的基本大纲,但其余部分留给您去解决,因为这是分配问题的主要症结所在。

let sum_lists lst1 lst2 =
  let rec sum_lists_helper lst1 lst2 carry =  
    match lst1,lst2 with
    | [],[] -> if carry = 1 then [1] else []
    | h::t,[]
    | [],h::t -> ...
    | h1::t1,h2::t2 -> ...
  in
  sum_lists_helper lst1 lst2 0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。