2015-01-01 23 views
0

为了避免任何误解,我在这里是新手,仍然是Java的初学者。我试图编写一个打印10,001st素数的代码。代码当前检查数字是否可以被数字2-9(包括)整除,然后检查数字的平方根是否是整数。查找10001素数 - 代码没有返回正确的数字

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); 
} 
} 

编辑:

我改变它,使它不再使用假的定义,但是这个新的代码没有输出,我没有看到与循环的任何问题。我也会尝试下面的其他建议,但想知道如何解决这个问题。

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); 
    } 
} 

谢谢。

+0

你的算法不正确。考虑数字11x13 = 143,这显然不是素数,不是方数,也不能被2,3整除。 –

+0

@Michael谢谢你指出。我现在正在使用不同的算法。如果你可以看看它,那会很好。 – Abdul97

回答

1

您的新版本不起作用,因为您正在测试从Math.sqrt(Num)降至1的所有数字,而不是所有数字降至2. 1总是正好进入每个数字,因此您的程序不会认为任何数字是总理,并永远运行。

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

+0

感谢您的建议。我的'Counter'和'Num'分别是4和8(忘记分别将值改为0和1)。 它现在的作品。谢谢您的帮助。 – Abdul97

+0

没关系。我很高兴听到它的作品。 –

3

它不工作,因为你的素数的定义不正确。

例如,数量437不是素数,因为它是19 * 23,但它会通过您的电流试验。

你的算法需要检查有问题的数量不能被整除任何素数截至及包括你正在检查的数量的平方根。

+0

关于如何改进/纠正它的任何建议?将测试数字是否可以通过数量小于其平方根的整数? – Abdul97

+0

是的,这是可行的,但它需要小于或等于,而不是小于。 – Amber

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

我会使用基于埃拉托色尼的筛上的方法。问题是,既然你不知道10001素是什么,你不知道你的阵列有多大。你可以试着想一些大数字,并希望它足够大以容纳10001个素数,但如果它太大,你会做额外的工作。可能有一些公式可以帮助你提出一个近似值,并从那里开始。

另一种方法是,开始用较小的阵列,然后视需要扩展它。假设你从一个大小为1000的布尔数组开始,表示数字1到1000.执行筛选(从2开始;将2加到列表中,标记数组中所有2的倍数,找到下一个未标记的值,将其添加到列表中,标记所有倍数等)。这显然不会找到10001素数。因此,当你点击布尔数组的末尾时,清除它,然后更改一个“基本”变量,以便它现在代表1001到2000范围内的数字。检查已经建立的素数列表,以及标记所有倍数。现在所有未标记的值都是素数。将它们添加到列表中,清除数组,然后更改基数,以使数组现在代表数字2001至3000.遍历素数列表,标记倍数,并继续前进,直到列表大小达到10001为止。

我不知道这种方法与其他方法相比效率有多高,但直观地看起来好像比逐一查看所有数字并检查每个数字以获得除数更好。

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 ...