为什么最后一个“else”不使用新值重新启动递归?

问题描述 投票:0回答:2

所以我在大学学习 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 新手,我不知道如何找到导致问题的原因。

if-statement recursion ocaml
2个回答
1
投票

如果一个数恰好有两个不同的正因数: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

这就是我所能做到的了。


0
投票

您有几个案例。其中之一是:

begin 
print_int(p) ; 
print_int(q)
end

这涵盖了两个

mod
值不为 0 的情况。请注意,这种情况到此为止。打印这两个int后就没有什么可做的了。这就是为什么您的代码在第一次后停止的原因。对
calculpj
的两次递归调用适用于其他情况。

其他观察结果:

OCaml 中常见的不等于运算符是

<>
。您正在使用一种在学习后期之前应避免使用的工具:-)

你测试n是否> 0,这是有道理的。但是当它为 false 时,无论如何你都会递归地调用

calculpj
。这表明,如果您解决第一个问题,您将遇到无限循环。

不清楚您为什么要测试是否

q = p + 2
。如果您提供两个相差 2 的值,那么您的递归调用将导致它们始终相差 2。

© www.soinside.com 2019 - 2024. All rights reserved.