【问题标题】:Java function to find prime number not working查找素数的Java函数不起作用
【发布时间】:2014-03-23 05:20:00
【问题描述】:

该函数接受一个整数 N。该函数必须打印从 2 到 N 的所有素数(包括 N,如果 N 本身是一个素数)。

我有这个函数并且它运行了,但是它跳过了一些素数,甚至包括一些偶数,比如 8。我似乎找不到导致这种情况的错误。

我的代码如下所示:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class PrimeNumbers {

    List <Integer> primeList = new ArrayList<Integer>();
    public ArrayList<Integer> findPrimes(int n){

        if(n == 2){
            primeList.add(n);
        }
        else{
            //should I have i=i+2 instead of i++ to move faster? 
           //If so, by doing this, it causes weird and different 
          //output when running
            for(int i=2; i<=n; i++){
                if(n%i != 0){
                    primeList.add(i);
                }
            }

        }

        return (ArrayList<Integer>) primeList;
    }

    public static void main(String[] args) {
        PrimeNumbers pn = new PrimeNumbers();

        System.out.println(pn.findPrimes(15));
    }

}

【问题讨论】:

  • 你的逻辑有问题,你只需从 2 迭代到 n 一次,但你应该有一个函数来检查数字是否为素数,并在循环中调用该函数。
  • 我想要一个接收数字 N 并返回从 2 到 N 的所有素数组成的数组。
  • 创建一个函数来检查数字是否为素数,并返回布尔值 true 或 false。通过传递循环计数器作为参数在循环中调用该函数,如果函数返回 true,则将该数字添加到数组列表中
  • 您的算法不正确。如果它是素数,您必须检查每个“i”,但您要检查“n”是否可以被每个“i”整除。向 google 询问“prime sieve”,您将获得一个高效且有效的算法。
  • 只要在纸上做两个数字,你就会明白为什么你所做的与质数完全无关。您所做的就是找到n 的所有非因数。

标签: java arrays arraylist primes


【解决方案1】:

您查找素数的逻辑不正确。

现在,您的代码所做的是: 1. 迭代所有整数,直到 N 2. 找出任何 N 不能被除的整数,并将它们添加到列表中。 这与素数无关。

相反,您的代码应该执行以下操作: 1. 迭代所有整数,直到 N 2. 对于这些整数中的每一个(假设是 M),运行一个子循环迭代它下面的所有整数,并检查这些整数是否都不能整除 M。 如果子循环结束时没有找到 M 的除数,则将 M 添加到列表中 - 它是一个素数(不能被除 1 和自身之外的任何整数除)。

检查数字(2或以上)是否为素数的简单代码:

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

    return true;
}

对此有很多优化,它本身就是一个世界。

【讨论】:

  • 你能提供一个演示这个的sn-p代码吗
【解决方案2】:

你的逻辑完全是倒退的。如果您已经测试了所有可能的除数,您只能说一个数字是素数。您当前正在添加任何具有非零余数的数字,即 BACKWARDS。非零余数意味着它不能被整除,这意味着它不是您正在测试的因子的倍数,例如

8 % 3 -> 2
2 != 0 -> true
therefore 8 is prime

您只能在完成循环并且没有测试返回 true 之后进行 .add() 调用:

is_prime = true; // assume prime
for(i = 2; i <= n; i++) {
     if (n % 2 == 0) { // no remainder, even divisible, therefore NOT primt
         is_prime = false;
         break; // abort the loop, no point in testing more
     }
}

是的,您可以通过从 3 开始测试并跳 2 来提高效率。由于 2 是唯一的偶数,因此任何其他偶数实际上都不可能是质数,因为 2 是除数在所有偶数中。所以测试3、5、7、9等...

例如

  test if `n` is even and `!= 2` - if so, then it's NOT prime
  run 3,5,7,... loop to test everything else

【讨论】:

    【解决方案3】:

    您所做的只是找到n因数。如果n % i != 0 相加,您可以测试导致它的每个数字是否是n 的因子。

    您需要做的是从 2 迭代到 n,并且对于这些数字中的 每个,测试它是否为素数。您将需要两个循环。我建议创建一种确定素数的方法,我猜您当前的方法是按原样查找。只需将if (n % i != 0) 替换为if(isPrime(i))

    public static boolean isPrime(long n) {
        // eliminate the simple cases
        if (n < 2) {
            return false;
        } else if (n == 2) {
            return true;
        }
    
        // only test up until the square root of that number
        for (int i = 2; i < Math.pow(n, 0.5) + 1; i++) {
            if (n % i == 0) {
                return false; // found a factor, it's not prime
            }
        }
        return true; // hasn't found a factor and returned false, so it's prime
    }
    

    然后在你当前的代码中:

    for(int i=2; i<=n; i++){
        if(n%i != 0){
            primeList.add(i);
        }
    }
    

    只需将if(n%i != 0){ 更改为if(isPrime(i))

    原来是这样的:

    for(int i=2; i<=n; i++){
        if(isPrime(i)) {
            primeList.add(i);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多