Java 素数的计算方法

Java 素数的计算方法,java,math,primes,Java,Math,Primes,我试图弄清楚这个Java方法是如何计算素数的,但有些事情让我困惑 public static boolean isPrime(int number){ for(int divisor =2; divisor <= number / 2; divisor++){ if (number % divisor ==0){ return false; } } return true; } 正如您在for循环的第二行中看

我试图弄清楚这个Java方法是如何计算素数的,但有些事情让我困惑

public static boolean isPrime(int number){
    for(int divisor =2; divisor <= number / 2; divisor++){
        if (number % divisor ==0){
            return false;
        }
    }
    return true;
}
正如您在for循环的第二行中看到的,它首先显示除数,如果您将除数放在第一位,如果您将除数 }

}


原因是任何数字都不能被大于它一半的除数除,如果我们说的是整数,则给出的除数不能大于1。

原因是任何数字都不能被大于它一半的除数除,如果我们说的是整数,则给出的除数不能大于1,当然。

任何数字都不能被超过一半的数字整除

例如,最后一个10可以整除的数字是5。10不能被6、7、8或9整除


这就是为什么消除明显的不匹配可以提高算法性能的原因。

任何数字都不能被超过一半的数字整除

例如,最后一个10可以整除的数字是5。10不能被6、7、8或9整除


这就是为什么消除明显的不匹配有助于提高算法性能的原因。

它利用了一个事实,即如果一个因子大于N/2,另一个因子必须小于2

事实上,利用平方根可以得到大量的渐近增益

这是因为如果一个因子大于平方根,另一个因子则较小

对不起,塞布里·祖哈伊尔。我正在改变忠诚。 +1不是必需的,因此最好的答案如下。
我很抱歉为了这么小的进步而改变立场

它使用了一个事实,即如果一个因子大于N/2,另一个因子必须小于2

事实上,利用平方根可以得到大量的渐近增益

这是因为如果一个因子大于平方根,另一个因子则较小

对不起,塞布里·祖哈伊尔。我正在改变忠诚。 +1不是必需的,因此最好的答案如下。 我很抱歉为了这么小的进步而改变立场

数字N不能有任何大于N/2且小于N的除数D。要了解这一点,请注意,如果D是N的除数,则对于某些D2,它必须等于N/D2。所以N的除数是这个序列中的整数:N,N/2,N/3。。。这是一个递减序列。很明显,在N和N/2之间不可能有任何除数

事实上,检查素性的程序通常在sqrtN而不是N/2处停止。原因是:假设有一个除数D,使得D>sqrtN。那么N/D=D2也必须是N的除数。必须是D2sqrtN,那么D*D2必须>N,这是错误的,因为D*D2=N。这意味着不需要检查可能的除数D>sqrtN;如果存在这样一个除数,我们早就在循环中找到了D2,并证明了N不是素数。

数字N不能有任何大于N/2和
事实上,检查素性的程序通常在sqrtN而不是N/2处停止。原因是:假设有一个除数D,使得D>sqrtN。那么N/D=D2也必须是N的除数。必须是D2sqrtN,那么D*D2必须>N,这是错误的,因为D*D2=N。这意味着不需要检查可能的除数D>sqrtN;如果存在这样一个除数,我们早就在循环中找到了D2,并证明了N不是素数。

对上述一些答案的一个小警告是0和1不是素数。您可以使用以下实现来解释正整数的情况

public static boolean isPrime(int number){
    if (number == 0 || number == 1) 
        return false;
    else
    {
        int stop = (int) Math.sqrt(number);
        for (int divisor = 2; divisor <= stop ; divisor++) 
        {
               if (number % divisor ==0)
                    return false;

        }
            return true;

        }
    }

对上面的一些答案有一个小小的警告:0和1不是素数。您可以使用以下实现来解释正整数的情况

public static boolean isPrime(int number){
    if (number == 0 || number == 1) 
        return false;
    else
    {
        int stop = (int) Math.sqrt(number);
        for (int divisor = 2; divisor <= stop ; divisor++) 
        {
               if (number % divisor ==0)
                    return false;

        }
            return true;

        }
    }

正如其他人所指出的,没有大于n/2的因子。一个更好的解决方案是将迭代变量与n的平方根进行比较,就好像没有小于或等于平方根的因子一样,没有大于平方根的因子。注意,比较i*i更有效,正如其他人所指出的,没有大于n/2的因子。一个更好的解决方案是将迭代变量与n的平方根进行比较,就好像没有小于或等于平方根的因子,也没有比平方根更大的因子。注意,比较i*i替换除数更有效。像这样检查循环中的每个除数的想法有很多错误。这是非常浪费和低效的。你不需要检查是否可以被6整除

已经测试过2或3等。最佳情况下,你应该只检查以前的素数,直到rootnumber,但这需要存储它们。替换除数检查循环中的每个除数的想法有很多错误。这是非常浪费和低效的。如果你已经测试过2或3等,你不需要检查是否可以被6整除。最好只检查以前的素数,直到rootnumber,但这需要存储它们。哦,是的!我真傻,竟然忽略了那里的if语句。所以我认为在这种情况下,它应该是除数<数,以使它工作,虽然它不是必要的。。。但非常感谢您的详细解释!:很遗憾原来的代码没有意识到你不需要检查2的每一个除数。。。number/2或rootnum,但仅限于以前的素数。如果已经检查了2,为什么还要检查是否可以被4整除?或者6,如果你选择了3?对,平方根是一个更强的条件。你应该考虑一下@这绝对是真的!该算法提供了一个很好的机会,可以与您的学生讨论内存权衡的速度。这就是Dijkstra在第53页的《惊奇》一文中所讨论的。@user1579701如果你好奇的话,Dijkstra在1969年写的文章中对这个问题有一个惊人的处理。我在上面的评论中贴了一个链接。哦,yeees!我真傻,竟然忽略了那里的if语句。所以我认为在这种情况下,它应该是除数<数,以使它工作,虽然它不是必要的。。。但非常感谢您的详细解释!:很遗憾原来的代码没有意识到你不需要检查2的每一个除数。。。number/2或rootnum,但仅限于以前的素数。如果已经检查了2,为什么还要检查是否可以被4整除?或者6,如果你选择了3?对,平方根是一个更强的条件。你应该考虑一下@这绝对是真的!该算法提供了一个很好的机会,可以与您的学生讨论内存权衡的速度。这就是Dijkstra在第53页的《惊奇》一文中所讨论的。@user1579701如果你好奇的话,Dijkstra在1969年写的文章中对这个问题有一个惊人的处理。我在上面的评论中贴了一个链接。哦,对了!我太笨了,忘了可以简化它以减少不必要的检查。但真的谢谢你提醒我!:哦,对了!我太笨了,忘了可以简化它以减少不必要的检查。但真的谢谢你提醒我!:这个版本有很多问题。为什么你要测试2,3,4,5,6,7…中的每一个数字的可除性。。。?如果它不能被2整除,为什么选择4?和8。。。与3和6相同。。。您只需要检查以前的素数。此外,您的快速退出将在循环的第一次迭代中被选中,您真的认为它会捕获到那么多值得写入方法的情况吗?这个版本有这么多问题。为什么你要测试2,3,4,5,6,7…中的每一个数字的可除性。。。?如果它不能被2整除,为什么选择4?和8。。。与3和6相同。。。您只需要检查以前的素数。此外,您的快速退出将在循环的第一次迭代中被选中,您真的认为它将捕获许多值得写入方法的情况吗?这根本不是AKS。这根本不是AKS。
public static Boolean isPrime(int num){ //method signature. returns Boolean, true if number isPrime, false if not
if(num==2){ //for case num=2, function returns true. detailed explanation underneath
  return(true);
}
for(int i=2;i<=(int)Math.sqrt(num)+1;i++){ //loops through 2 to sqrt(num). All you need to check- efficient
  if(num%i==0){ //if a divisor is found, its not prime. returns false
    return(false);
  }
}
return(true); //if all cases don't divide num, it is prime.
    // Returns true iff n is prime.  First checks if n is even, handling the
// cases of n=2 (prime) or n is even > 2 (not prime).  Then checks if any
// odd #'s between 3 and sqrt(n), inclusive, are divisors of n, returning
// false if any are.
public static boolean isPrime(int n) {
    if (n < 2) return false;
    if (n % 2 == 0)
        // n is an even, so return true iff n is exactly 2
        return (n == 2);
    for (int i=3; i*i<=n; i+=2)
        if (n % i == 0)
            // i divides evenly into n, so n is not prime
            return false;
    return true;
}
public static boolean isPrime(int number){
    if (number == 0 || number == 1) 
        return false;
    else
    {
        int stop = (int) Math.sqrt(number);
        for (int divisor = 2; divisor <= stop ; divisor++) 
        {
               if (number % divisor ==0)
                    return false;

        }
            return true;

        }
    }
public static boolean isPrime(long n) { 
    /* This code uses the AKS primality test
     * http://en.wikipedia.org/wiki/AKS_primality_test
     */
    if (n <= 3) return n > 1;
    if (n % 2 == 0 || n % 3 == 0) return false;
    for (int i = 5; i*i <=n; i+=6) {
      if (n % i == 0 || n % (i+2) == 0) return false; 
    }
    return true;
  }
}
public class PrimeCounter {
  public static void main(String[] args) {
    long n = 10000000;
    long count = 0;
    for (long i = 0; i <= n; i++) {
      if (isPrime(i)) count++;
    }
    System.out.println("The number of primes less than "
                         + n + " is " + count);
  }


  public static boolean isPrime(long n) { 
    /* This code uses the AKS primality test
     * http://en.wikipedia.org/wiki/AKS_primality_test
     */
    if (n <= 3) return n > 1;
    if (n % 2 == 0 || n % 3 == 0) return false;
    for (int i = 5; i*i <=n; i+=6) {
      if (n % i == 0 || n % (i+2) == 0) return false; 
    }
    return true;
  }
}