所以我在大学学习 Ocaml,今年我们创建的代码有一些特殊的规则:没有循环或数组(我不知道为什么,但当我的一个朋友在考试中使用它们时,她几乎看起来很生气)所以我们必须处理仅递归的问题,在这里我必须创建一个代码来返回 (0,2) 和 (n,n+2) 之间的所有孪生素数,例如 3,5 5,7 或 11,13 所以我尝试这样做就这样:
let rec calculpj p q n =
if q = p + 2 && n > 0 then begin
if q mod p != 0 && p mod q != 0 then begin
print_int(p) ;
print_int(q) end
else calculpj (p + 1) (q + 1) (n - 1) end
else calculpj (p + 1) (q + 1) (n - 1) ;;
calculpj 3 5 3
但出于某种原因,我无法理解为什么最后一个“else”不使用新值重新启动递归,因为第一个“循环”按预期返回值。 如果有人想知道这个练习来自哪里,那就是来自一次考试,老师没有给我们答案,所以我没有任何东西可以纠正自己。
我尝试了很多方法,但由于我是 Ocaml 新手,我不知道如何找到导致问题的原因。
如果一个数恰好有两个不同的正因数:1 和该数本身,则该数是素数。因此,创建一个使用这些特征来测试它是否是素数的函数:
## pseudo code
Function is_prime(n)
Function check(i)
If i * i > n Then
Return true
Else If n mod i = 0 Then
Return false
Else
Call check(i + 1)
End Function
If n > 1 and check(2) Then
Return true
Else
Return false
End Function
所以现在的主要游戏是通过递归重复数字,所以你需要一个明确的方法来突破。我建议你只要求一些对,一旦达到,回避就会结束。下面的参数
n
对于找到的每对都会减少 1,并在达到 0 时退出。第二个参数 start
只是允许您指定起始点,例如1
## pseudo code
Function twin_primes(n, start)
Function helper(p, q, n, result)
If n equals 0 Then
Return result
Else If p and q are twin primes Then
Decrease n by 1
Add (p, q) to result
Call helper(p + 1, q + 1, n, result)
Else
Call helper(p + 1, q + 1, n, result)
End Function
Call helper(start, start + 2, n, empty list)
End Function
这就是我所能做到的了。
您有几个案例。其中之一是:
begin
print_int(p) ;
print_int(q)
end
这涵盖了两个
mod
值不为 0 的情况。请注意,这种情况到此为止。打印这两个int后就没有什么可做的了。这就是为什么您的代码在第一次后停止的原因。对 calculpj
的两次递归调用适用于其他情况。
其他观察结果:
OCaml 中常见的不等于运算符是
<>
。您正在使用一种在学习后期之前应避免使用的工具:-)
你测试n是否> 0,这是有道理的。但是当它为 false 时,无论如何你都会递归地调用
calculpj
。这表明,如果您解决第一个问题,您将遇到无限循环。
不清楚您为什么要测试是否
q = p + 2
。如果您提供两个相差 2 的值,那么您的递归调用将导致它们始终相差 2。