蛮力方法寻找素数

时间:2013-05-24 01:57:08

标签: java math primes

我在编写一个找到2-50之间的素数的程序时遇到了麻烦。我的程序现在找到“大多数”素数,但包括一些非素数。我知道有更多有效的方法和策略可以找到素数,但我在尝试更有效和更有效的策略之前,首先要尝试各种可能性。现在编写程序的方式,如果它确实找到一个素数,它会多次打印它,而我只想打印一次。我的程序在概念上是正确的还是我的理由存在缺陷。为什么我的程序主要找到素数但是抛出一些非素数?为什么我的程序多次打印素数?

以下是我解决问题的方法。

  1. 创建一个for循环来表示2-50之间的潜在素数。用变量“i”表示这些潜在的素数。此循环将从50开始倒计时。

  2. 由于只有在除了自身和1之外没有其他可分数的情况下,数字才是素数,我想创建一个内部for循环,将i除以2和i -1之间的每个可能数,以查看是否有任何这些数字均匀分为i。用变量j表示这些可能的除数。如果在任何时候j确实均分为i,那么它不是素数,所以我希望我的内循环退出。

  3. 如果我被j的所有数字除以并且没有数字均匀分配到i那么该数字如果是素数并且想要打印该数字。

  4. *

    import acm.program.*;
    public class PrimeNumber extends ConsoleProgram{
    public void run(){
    
      for (int i =50; i >= 2; i--){
        for (int j= 2; j < i-1; j++){
    
            if (i % j >= 1){
             println(i);
             }else{
             if (i % j == 0) break;
                    }
                  } /*end of inner loop */  
               } /* end of for loop */
    
           } /* end of run method */
         } 
    

7 个答案:

答案 0 :(得分:2)

你犯了2个错误。第一个问题在@Thomas的评论中进行了解释,第二个问题在@rolfl的评论中进行了解释。我在这里纠正了他们:

public class PrimeNumber extends ConsoleProgram {
    public void run() {
        for (int i = 50; i >= 2; i--) {
            boolean isPrime = true;
            for (int j = 2; j < i-1; j++) { //increment "j" not "i"
                if (i % j == 0) {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime) System.out.println(i);
        }
    } 
}

注意:我使用此代码验证了解决方案(在IDE中保存为PrimeNumber.java):

public class PrimeNumber {
    public static void main (String args[]) {
        for (int i = 50; i >= 2; i--) {
            boolean isPrime = true;
            for (int j = 2; j < i-1; j++) { //increment "j" not "i"
                if (i % j == 0) {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime) System.out.println(i);
        }
    } 
}

编辑:为了您的理解,您的主要问题是这里的逻辑:

for (int j= 2; j < i-1; j++) {
    if (i % j >= 1) {
        println(i);

仅在检查一种可能性后打印i

例如,取i = 7。您必须先对i % j = 6,5,4,3和2进行j测试,然后才能说i为素数。正如您所做的那样,您不能只为i % j测试j = 6。为此,您的println语句应该在for循环之后,而不是嵌套在其中,因此您可以首先测试j的所有可能值。


编辑2:以回应

  

巧合的是,赋值的第一部分是编写一个谓词方法,如果数字是素数则返回true,如果不是使用蛮力策略则不是素数。任务的第二部分是找到一种更有效的方法,并重新完成任务的第一部分,以提高效率。我试图使用两个for循环来解决问题,看看我是否可以做到这一点。可以用两个没有标签的for循环完成,并继续,因为我的书尚未涉及到吗?

尝试这样的事情:

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

答案 1 :(得分:1)

您正确地注意到,如果数字i可以平均分为数字j,那么i % j == 0

但是,每当您发现i % j >= 0的情况时,您就会打印我 - 这并不意味着i是素数,因为可能还有其他j i可以平均分为。

相反,您应首先浏览所有j,并且只有在没有人提供== 0的情况下,您才应该考虑i素数。您可以使用最初为isPrime的布尔变量true,但是一旦找到false j,内部for循环就会设置为i {{1}}可以均分。

答案 2 :(得分:1)

第二个循环(内循环)中存在错误。

你应该递增j而不是i ....即内在循环应该是

for (int j= 2; j < i-1; j++){

而不是

for (int j= 2; j < i-1; i++){

答案 3 :(得分:0)

这个if语句:

if (i % j >= 1){
         println(i);

将打印未除以j编号的每个数字,并且您要打印的数字不是那些从一个减法中得到除以0的除法值的数字,而是用于所有子数。

更快的解决方案是采用潜在质数的布尔数组并像这样循环。

for ( i = 2; i < sqrt(maxvalue); i ++){
            for(j = 1; j < sqrt(maxval); j++){
                  potentialy_prime[i*j]=false
            }
       }
for (potentialy_prime){
    if(potentialy_prime[i]==true)
            print(i "is prime")
}

答案 4 :(得分:0)

查看dydx关于这个问题的答案:https://stackoverflow.com/questions/13437162/java-finding-prime-numbers。或者这个问题:Prime number calculation fun或者这个Getting the prime numbers等等......

答案 5 :(得分:0)

您的代码有3个问题:

  • 在内部循环中,您正在增加i而不是增加j

  • 您可以尽快打印该号码i % j >= 1,但下一个j可能会划分i,因此i不是素数。

  • 你应该在sqrt(i)停止内循环,以避免无用的测试。

以下是代码的更正版本:

OUTER: for (int i = 50; i >= 2; i--) {
    for (int j = 2; j <= (int) Math.sqrt(i); j++) {
        if (i % j == 0)
            continue OUTER;
        } /* end of inner loop */
    println(i);
} /* end of for loop */

答案 6 :(得分:0)

此代码应打印出素数。初始假设是每个整数&gt; = 2都是素数(在布尔数组中为真)。遍历数组时,如果发现数字为素数,则通过在布尔数组中将它们设置为false来交叉出该数字的倍数(因为它们不是素数)。最后,布尔数组中的数字为true,仅为素数。

时间复杂度:O(n log(log n))

public class PrimesImprovement
{
    public static void main(String[] args)
    {  
        System.out.println("Printing primes from 1 to 100");
        int i;
        int j;
        //boolean prime;
        boolean[] prime_arr=new boolean[100];
        Arrays.fill(prime_arr,true); // Assumption
        prime_arr[0]=prime_arr[1]=false;  // As 0 and 1 are not prime numbers
        for ( i=2;i<prime_arr.length;i++) 
        {

            if(prime_arr[i])
            { 
                for ( j=2;i*j<prime_arr.length;j++) 
                {
                    prime_arr[i*j]=false;
                }
            }
        }

        for( i=0; i<prime_arr.length; i++)
        {
            if(prime_arr[i])
            {
                System.out.print(i+" ");
            }
        }

        System.out.println();
    }
}