使用尾部递归在Scala中实现isPrime

时间:2019-01-07 21:00:37

标签: algorithm scala primes

我正在做一个练习,要求我使用尾部递归在scala中实现isPrime。我确实有一个实现,但是在生成正确的基本案例时遇到了问题。

所以我的算法涉及检查2到N / 2之间的所有数字,因为N / 2是N的最大因子。

def isPrime(n: Int): Boolean = {
    def isPrimeUntil(t: Int): Boolean = {
        if(t == 2) true
        else n % t != 0 && isPrimeUntil(t - 1)
    }

    isPrimeUntil(n/2)
}

因此,基本上,如果我想检查15是否为质数,我将检查从7到2的所有数字。

这是我的踪迹:

isPrimeUntil(7) -> true && isPrimeUntil(6) -> true && isPrimeUntil(5) -> false && isPrimeUntil(4)

由于短路评估,该函数此时返回false。

但是,对于检查3是否为质数的基本情况,我的实现失败。

2 个答案:

答案 0 :(得分:2)

3并不是您唯一的问题。它还为{'42': 'foo'}返回true ... 您的基本情况应为4,而不是1

2

答案 1 :(得分:1)

尽管Krzystof正确指出问题的根源是整数除法,但我不喜欢他的解决方案。我相信正确的解决方法是将测试更改为

 if(t <= 2) true

n = 3的情况下进行了这样的检查,因此n/2 = 1会停止而不会转到t = 0

一些好处:

  • 几乎所有现代硬件上经过修改的支票(t <= 2)(t == 2)支票一样有效
  • 恕我直言,它更好地传达了逻辑
  • 以这种方式编写(n.toDouble/2).ceil.toInt的效率非常低。编写(n+1)/2而不是进行2转换(将其翻倍并返回int)更容易,更快捷
  • 不需要对所有奇数n进行过多检查({{1}永远不是奇数(n+1)/2的最小除数,nn/2