这两种检查一个数是否为质数的方法有什么区别?

4

我写了一个检查数字是否为质数的方法:

static boolean isPrime(int x) {
        for (int i = 2; i <= Math.sqrt(x); i++) {
            if (x % i == 0)
                return false;    
        }
        return true;
    }

在我们学习的一系列练习中,解决方案是:
static boolean isPrime(int x) {
    boolean hasDivisors = false;
    for (int i = 2; i <= Math.sqrt(x); i++) {
      if (x % i == 0) {
        hasDivisors = true;
        break;
      }
    }
    return !hasDivisors;
}

在我的情况下,如果我找到了一个除数,我会返回这个数不是素数(return false),这样就可以替代第二种方法中需要使用break的步骤。另一个明显的原因是第二种方法只使用了一个return语句。
这么做是否有速度和内存方面的原因呢?

第二种方法更易读和理解。就性能而言,两种方法是相同的。 - Rahul Bobhate
3
不,这只是风格问题。 - RealSkeptic
唯一的区别在于官方解决方案对初学者来说稍微容易理解一些。就我所看到的,运行时间或内存消耗没有真正的区别。 - Patrick
3
我更喜欢第一种方法。第二种方法看起来过于臃肿。在大型函数中,早期退出可能会令人困惑,但我认为在小型函数中更易读。每当我编写一个简单的素数查找函数时,它几乎总是像您的版本一样。 - Carcigenicate
2个回答

5

这主要是风格问题。一些编码规范要求一个方法只有一个return语句。在那些需要显式释放资源的语言中,这种做法很有道理,但在Java中没有任何功能影响。

个人而言,我更喜欢像第一个片段中那样,在知道结果后立即return,但再次强调,这是个人风格问题。


3
两种解决方案都可行,都是基于你已经发现的所有原因。分析得很好。正如其他人所指出的那样,差异纯粹是风格上的。这里有一个关于Java中单个返回语句风格的有趣讨论。
就性能而言,我不认为这两种方法之间会有显著的差异。但如果您想要确定,可以进行基准测试。如果您想要真正的性能提升,可以通过替换来消除昂贵的Math.sqrt()调用:
for (int i = 2; i <= Math.sqrt(x); i++) {

使用

for (int i = 2; i*i <= x; i++) {

1
或者在循环外部调用sqrt一次并缓存结果以获得更快的速度。尽管如此,仍然无法与最先进的素数测试器相匹配^^ - AlexR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接