我正在做一个练习,要求我使用尾部递归在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是否为质数的基本情况,我的实现失败。
答案 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
的最小除数,n
和n/2
)