查找第10001个素数 - 代码未返回正确的数字

时间:2015-01-01 03:19:30

标签: java numbers

为了避免任何误解,我是新来的,仍然是Java的初学者。我正在尝试编写一个打印10,001个素数的代码。代码当前检查该数字是否可被数字2-9(包括)整除,然后检查该数字的平方根是否为整数。

public static void main(String[] args){
  Integer Num , Counter;
  Double Sqrt; //square root
  Num=8;
  Counter=4 ;
  while(Counter<10001){
    Num++;
    if ((Num%2!=0) && (Num%3!=0) && (Num%4!=0) && (Num%5!=0) && (Num%6!=0) && (Num%7!=0) &&   (Num%8!=0) && (Num%9!=0)){
    Sqrt = Math.sqrt(Num);    
    if(Sqrt%1!=0){
      Counter++;
     }
   }
 }

 System.out.println(Num); 
 }
}

编辑:

我更改了它以便它不再使用false定义,但是使用这个新代码没有输出,我没有看到循环有任何问题。我还将尝试下面的其他建议,但想知道如何解决这个问题。

 public static void main(String[] args)
   {
 int Num , Counter;
 double Sqrt; //square root
 Num=1;
 Counter=0 ;

 while(Counter<10001){
   Num++;
   Sqrt = Math.sqrt(Num);
   int i = (int)Sqrt;
    while(i>1){
       if(Num%i==0){ //if the number is divisible then the loop is terminated and next number is tested
        i=0;
                   }
        i--;
              }

      if(i==1){
     Counter++;
              }
 }

 System.out.println(Num);   
  }
 }

感谢。

5 个答案:

答案 0 :(得分:4)

你的逻辑是有缺陷的。例如,在检查数字143时,您的代码认为它是素数。但是,11 * 13 = 143,所以它实际上不是素数。我建议创建一个素数列表,并通过列表执行for-each循环。

List<Integer> primes = new ArrayList<Integer>();
int number = 2;
while (primes.size() < 10001) {
   boolean isPrime = true;
   for (Integer prime : primes) {
      if (number % prime == 0) {
         isPrime = false;
         break;
      }
   }
   if (isPrime) {
      primes.add(number)
   }
   number++;
}
System.out.println(primes.get(10000));

这可能不是一个快速的解决方案,但它应该工作......虽然没有测试。祝你好运:)。

答案 1 :(得分:3)

它无效,因为您对素数的定义不正确。

例如,数字437不是素数,因为它是19 * 23,但它会通过你当前的测试。

您的算法需要检查相关数字是否可以被任何素数整除,包括您要检查的数字的平方根。

答案 2 :(得分:1)

您的新版本无法正常运行,因为您正在测试从Math.sqrt(Num)到1的所有数字,而不是所有数字都会降至2. 1始终完全进入每个数字,因此您的程序不会认为任何数字数字是素数,并且永远运行。

要使其有效,您需要将while(i>0)更改为while(i>1)。您还需要将if(i==0)更改为if(i==1)。我也不确定为什么NumCounter的值为8和4.我会让你弄清楚它们应该是什么。

答案 3 :(得分:0)

在这里,您将找到另一种(紧凑的)方法,用于生成由const MAX(生成的元素数量)限制的素数序列,使用Stream类(对于生成的每个x,过滤器拒绝不可分割的x仅限x:一个只能被自身整除的数字,而1是素数):

public class PrimeNumbersSeq {

    final private static Long MAX=10001l;

    public static void main(String[] args) {
    System.out.println(LongStream
            .iterate(2, x -> x + 1)
            .filter((i) -> LongStream.range(2, i)
            .noneMatch(j -> i % j == 0)).limit(MAX)
            .mapToObj(String::valueOf)
            .collect(Collectors.joining(",", "[", "]")));
    }
}

产出:[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79, 83,89,97,101 ...

答案 4 :(得分:-1)

我会使用基于Eratosthenes筛子的方法。问题是,由于你不知道第10001个素数是什么,你不知道你的阵列有多大。你可以尝试考虑一些大数字,并希望它足够大,可以容纳10001个素数,但如果它太大,你将会做更多的工作。可能有一些公式可以帮助你提出近似值,并从那里开始。

另一种方法是从较小的数组开始,然后根据需要扩展它。假设您从一个大小(例如)1000的布尔数组开始,表示数字1到1000.执行筛(从2开始;在列表中添加2,在数组中标记所有2的倍数,找到下一个未标记的值,将其添加到列表中,标记所有的倍数,等等。这显然不会找到第10001个素数。所以当你点击布尔数组的末尾时,清除它然后改变一个&#34; base&#34;变量,现在它表示1001到2000范围内的数字。浏览已经建立的素数列表,并标记所有倍数。现在所有未标记的值都是素数。将它们添加到列表中,清除数组,然后更改基数,以便数组现在表示数字2001到3000.浏览素数列表,标记倍数,并继续前进,直到列表大小达到10001.

我不知道这种方法与其他方法相比有多高效,但直观地说,它似乎比逐个查看所有数字并检查除数的每个数字更好。