非常简单的素数测试 - 我想我不理解for循环

问题描述 投票:13回答:12

我正在练习过去的基础java考试的考试试卷,我发现很难做一个for循环工作来测试一个数字是否是素数。我不想通过为更大的数字添加效率测量来使其复杂化,这只是至少适用于2位数字的东西。

目前,即使n是素数,它总是返回false。

我认为我的问题是我在for循环本身出错了,在哪里放“return true”。并且“返回虚假;”......我确信这是我犯的一个非常基本的错误......

public boolean isPrime(int n) {
    int i;
    for (i = 2; i <= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

我无法在stackoverflow上找到其他帮助的原因是因为类似的问题要求更复杂的实现以获得更有效的方法。

java loops for-loop iterator primes
12个回答
31
投票

你的for循环有一点问题。它应该是: -

for (i = 2; i < n; i++)  // replace `i <= n` with `i < n`

当然,当n除以n时,你不想检查余数。它会永远给你1

实际上,您甚至可以通过将条件更改为: - i <= n / 2来减少迭代次数。由于n不能除以大于n / 2的数字,除非我们考虑n,我们根本不需要考虑。

所以,你可以将你的for循环改为: -

for (i = 2; i <= n / 2; i++)  

0
投票

上面提到的算法将1视为素数,尽管它不是。因此,这是解决方案。

static boolean isPrime(int n) {
  int perfect_modulo = 0;
  boolean prime = false;

  for ( int i = 1; i <=  n; i++ ) {
    if ( n % i == 0 ) {
      perfect_modulo += 1;
    }
  }
  if ( perfect_modulo == 2 ) {
    prime = true;
  }

  return prime;
}

0
投票

好吧,for循环有一些问题。这是代码,

public static boolean checkPrimeNUmber(int number) 
{ 
   if(number <= 1) 
   { 
      return false; 
   } 
   for(int a = 2; a < Math.sqrt(number); a++) 
   { 
      if(number % a == 0) 
      { 
         return false; 
      } 
   } 
   return true;
}

0
投票

这样做Java 8的方式更好,更清洁

    private static boolean isPrimeA(final int number) {
        return IntStream
               .rangeClosed(2, number/2)
               .noneMatch(i -> number%i == 0);
    }

31
投票

您可以提前停止并更快地跳过循环:

public boolean isPrime(long n) {
    // fast even test.
    if(n > 2 && (n & 1) == 0)
       return false;
    // only odd factors need to be tested up to n^0.5
    for(int i = 3; i * i <= n; i += 2)
        if (n % i == 0) 
            return false;
    return true;
}

3
投票

错误是i <= n

for (i = 2; i<n; i++){

3
投票

你应该写i < n,因为最后一次迭代步骤会给你true


2
投票
public class PrimeNumberCheck {
  private static int maxNumberToCheck = 100;

  public PrimeNumberCheck() {
  }

    public static void main(String[] args) {
      PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();

      for(int ii=0;ii < maxNumberToCheck; ii++) {
        boolean isPrimeNumber = primeNumberCheck.isPrime(ii);

      System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
    }
  }

  private boolean isPrime(int numberToCheck) {    
    boolean isPrime = true;

    if(numberToCheck < 2) {
      isPrime = false;
    }

    for(int ii=2;ii<numberToCheck;ii++) {
      if(numberToCheck%ii == 0) {
        isPrime = false;
        break;
      }
    }

    return isPrime;
  }
}

1
投票

使用此代码可以将3整除,将跳过for循环代码初始化。 对于循环迭代,也将跳过3的倍数。

private static boolean isPrime(int n) {

    if ((n > 2 && (n & 1) == 0) // check is it even
       || n <= 1  //check for -ve
       || (n > 3 && (n % 3 ==  0))) {  //check for 3 divisiable
            return false;
    }

    int maxLookup = (int) Math.sqrt(n);
    for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
        if (n % (i+2) == 0 || n % (i+4) == 0) {
            return false;
        }
    }
    return true;
}

1
投票

您还可以在for循环中使用一些简单的Math属性。

数字'n'将是素数,当且仅当它可被自身整除或1.如果数字不是素数,它将有两个因素:

n = a * b

你可以使用for循环来检查数字'n'的sqrt,而不是一直到'n'。如果'a'和'b'都大于数字'n'的sqrt,a * b将大于'n'。因此,至少有一个因素必须小于或等于平方根。

所以你的循环将如下所示:

for(int i=2; i<=Math.sqrt(n); i++)

通过这样做,您将大大减少代码的运行时复杂性。我认为这将归结为O(n / 2)。


1
投票

最快的方法之一是循环直到n的平方根。

  private static boolean isPrime(int n){
        int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
        HashSet<Integer> nos = new HashSet<>(); 
        for(int i=1;i<=square;i++){
            if(n%i==0){
                if(n/i==i){
                    nos.add(i);
                }else{
                    nos.add(i);
                    int rem = n/i;
                    nos.add(rem);
                }
            }
        }
        return nos.size()==2;//if contains 1 and n then prime
    }

0
投票

你正在检查i<=n.So当i==n,你将只得到0并且它将永远返回false。尝试i<=(n/2).No需要检查直到i<n

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