素数发生器逻辑

时间:2013-12-06 23:15:43

标签: java primes

我应该创建一个类PrimeNumberGenerator,它有一个方法nextPrime,可以打印出所有素数,直到用户输入的数字。

前)

Enter a Number: 
20
2
3
5
7
11
13
17
19

我们的老师告诉我们,我们应该使用嵌套的for循环。我试过了,但是当我试图制作内部(嵌套)循环时,我真的很困惑。

这是我的代码: (我稍后会做一个测试课)

public class PrimeGenerator {

    private int num;
    boolean isPrime;

    public PrimeGenerator(int n)
    {
        num = n;
    }

    public int nextPrime (int num)
    {
        for (int i=2; i < num; i++) // The first prime number is 2 and the prime numbers only have to go up to a number the user inputs. 
        {
            for (int j = 3; j<=i/2; j+=2) // The next prime number is 3 and I attempted to loop through to get the next odd number.
            {
                if (num % i == 0) //if the number (upper limit) mod a "prime number" is 0, then that means that number is not really "prime" after all. 
                {
                    break;
                }
            }
        }

        return num;
    }

}

15 个答案:

答案 0 :(得分:7)

这里有两个你忘了问的问题:

  • 为什么嵌套循环会使一切变得如此复杂?
  • 我可以做些什么来使事情再次复杂化?

让我们一起玩你实际提出的问题,然后回答前两个问题。

您想要做的事情可能是这样描述的: 对于每个数字,1-n,其中n由用户输入,如果它是素数,则打印出来。

好的,让我们在这里写下伪代码/逻辑。 它看起来像Java,但它不是。它只是意味着传达我们的目标:

int largestNumber = readIntegerFromKeyboard();

for all ints i from 1 to largestNumber {
    if(isPrime(i)) {
        println(i);
    }
}

所以,让我们这样做!但首先,我们需要一份清单,列出我们需要做的所有事情:

  • 从键盘读取整数
  • 循环数字
  • 检查号码是否为素数
  • 打印素数(换行)

让我们先做两件容易的事。读取输入并设置循环:

Scanner keyboard = new Scanner(System.in);
int largestNumber = keyboard.nextInt();

for(int i = 1; i <= largestNumber; ++i) {
    if(isPrime(i)) {
        System.out.println(i);
    }
}    

keyboard.close();

好的,这看起来很简单。到目前为止,这里的一切都有意义。理解逻辑很容易。 然而,现在,当我们用实际逻辑替换isPrime时,一切都将变得混乱并且难以阅读。

因此,让我们尽可能简单地理解这段代码。我们将不使用任何技巧来加速代码。可读性和正确性是唯一我们将关心的两件事。我们将使用模运算符来检查某些东西是否可以均匀分割。 Modulo就像整数除法,除了它返回余数而不是结果。所以7/2 = 2. 7%2 = 1,因为还剩下一个。

Scanner keyboard = new Scanner(System.in);
int largestNumber = keyboard.nextInt();

for(int i = 1; i <= largestNumber; ++i) {
    // checks if the number is a prime or not
    boolean isPrime = true;
    for(int check = 2; check < i; ++check) {
        if(i % check == 0) {
            isPrime = false;
        }
    }
    if(isPrime) {
        System.out.println(i);
    }
}    

所以好消息是,这是有效的。 坏消息是,这比必要的阅读更难。我们在这里做的不是很多。当我写这篇文章时,我犯了几个愚蠢的错误,混淆了变量。也许我愚蠢。所以也许我应该在那种情况下写出愚蠢的代码。 ;)另一方面,你不是傻瓜。但你可能和我一起工作, 愚蠢,所以你必须自己编写愚蠢的代码,这样你才能有效地与我合作。

最大的问题是我们在另一个循环的中间有这个庞大的循环。这就是让我失望的原因。我提到了错误的循环变量。但为什么我们需要循环中的循环?读起来不是很舒服:

if(isPrime(i)) {
    System.out.println(i);
}

而不是整个混乱?你的教授指出了嵌套循环。但是它让你失望了。相反,只需编写isPrime方法即可。事实是,对于我遇到过的每一个嵌套循环实例都是如此。所以让我们看看它会是什么样的:

class Homework {
    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        int largestNumber = keyboard.nextInt();

        for(int i = 1; i <= largestNumber; ++i) {
            if(isPrime(i)) {
                System.out.println(i);
            }
        }
        keyboard.close();
    }

    /**
     * Checks is a positive integer is a prime number
     */
    public static boolean isPrime(int number) {
        for(int check = 2; check < number; ++check) {
            if(number % check == 0) {
                return false;
            }
        }
        return true;
    }
}

这对我来说更容易阅读。不是因为逻辑变得更容易,而是因为 我不得不关心的事情是:

  • 检查所有数字并打印正确的数字,或
  • 如何检查数字是否为素数。

由于这两个不同的东西现在是分开的,所以你可以立刻想一想。高兴,因为你刚刚做了一个适当的抽象。这使您的代码更容易理解,因为它将这两个问题分开。这是制作大型项目的关键方式。你采取困难的事情并自己做。然后你可以自己测试它们,并自己使用它们。

(现在我只需等待回答一个你没有明确要求的问题的誓言......)

答案 1 :(得分:3)

我知道这个问题暂时存在,但由于没有人发布java8 / stream方法解决方案,这里有一种可行的方法。

Gist可以分叉here

打印输出:[1,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]

import java.util.*;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;


public class PrimeNumber {

     /**
     * Java 8 / Lambda approach to generate Prime number.
     * Prime always start to look from number 1.
     * @param series Number of how many Prime number should be generated
     * @return List holding resulting Prime number.
     */
    public static List<Integer> generate(int series) {
        Set<Integer> set = new TreeSet<>();
        return Stream.iterate(1, i -> ++i)
                .filter(i -> i %2 != 0)
                .filter(i -> {
                    set.add(i);
                    return 0 == set.stream()
                            .filter(p -> p != 1)
                            .filter(p -> !Objects.equals(p, i))
                            .filter(p -> i % p == 0)
                            .count();
                })
                .limit(series)
                .collect(toList());
    }

    // Let's test it!
    public static void main(String[] args) {
        List<Integer> generate = PrimeNumber.generate(20);
        System.out.println(generate);
    }
}

答案 2 :(得分:2)

根据Eratosthenes的筛子检查此算法的素数。当然,您需要根据您的计划进行调整。

boolean isPrime[] = new boolean [N+1];
for (int i=2; i <=N; i++)
    isPrime[i] = true;

//mark non-primes <=N using Sieve of Eratosthenes
for (int i=2; i*i<=N; i++) 
{
    //if is a prime,then mark multiples of i as non prime 
    for (int j=i; i*j<=N; j++) 
    {
        isPrime[i*j] = false;
    }
}

for (int i=2; i<=N; i++) 
    if (isPrime[i])
        //Do something.......   

答案 3 :(得分:1)

要生成素数,只需循环一个给定的数字,然后检查该数字是否为素数。 对于有效的素数生成,IsPrime方法必须非常高效和快速。 所以这里是代码来检查给定的数字是否为素数或非效率。

public static boolean IsPrime(int n) {

    if (n > 2 && n %2 == 0){
        return false;
    }
    int top = (int)Math.sqrt(n)+1;
    for (int i=3;i<top;i+=2){
        if (n%i==0){
            return false;
        }
    }
    return true;
}

以下代码将生成介于1和给定数字之间的素数。

 public class GeneratePrimeNumber {
    public static void main(String[] args) {
    System.out.println("Enter number to get prime number");
    int n = new Scanner(System.in).nextInt();
        for (int j=0;j<n;j++){
            if (IsPrime(j)){
                System.out.print(j + " ");
            }
        }

    }
 }

答案 4 :(得分:1)

我认为可以有更快的解决方案......

我们都知道2是第一个素数,素数是一个可以被1和它自身整除的素数。

设N =用户输入的数字,直到我们必须打印素数。 现在,

import numpy as np
import pandas as pd
from scipy import sparse

obs = np.random.randint(0, 2, 50)
pred = np.random.randint(0, 2, 50)
vals = np.ones(50).astype('int')

con = sparse.coo_matrix((vals, (pred, obs)))
print (con.todense()) 

答案 5 :(得分:0)

素数的简单定义:只能被1和1整除的数字。根据定义,1不是素数。这是一个强力算法,用于确定数字是否为素数。

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

答案 6 :(得分:0)

尝试使用此代码生成素数系列

public class prime1 {

public static void main(String[] args) {

    int max = 100;

    System.out.println("Generate Prime numbers between 1 and " + max);

    // loop through the numbers one by one
    for (int i = 1; i < max; i++) {

        boolean isPrimeNumber = true;

        // check to see if the number is prime
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                isPrimeNumber = false;
                break; // exit the inner for loop
            }
        }

        // print the number if prime
        if (isPrimeNumber) {
            System.out.print(i + " ");
        }
    }

}

}

答案 7 :(得分:0)

公共类PrimeNumberGeneration {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    Scanner scan = new Scanner(System.in);
    int n = scan.nextInt();

    ArrayList<Integer> primeNumbers = new ArrayList<Integer>();
    primeNumbers.add(2);
    System.out.println(2);

    no_loop:
    for(int no=3; no<=n; no+=2){
        for(Integer primeNumber: primeNumbers){
            if((no%primeNumber)==0){
                continue no_loop;
            }
        }
        primeNumbers.add(no);
        System.out.println(no);
    }

}

}

答案 8 :(得分:0)

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.soap.Node;

public class mainone {

 public static void main(String args[]){

    int[] primenumber=new int[13];

    for(int a=2,j=0;a<=14;a++,j++){
        primenumber[j]=a;

    }

    for(int b=1;b<13;b++){
        int d=primenumber[b];
        if(d%2==0){
            primenumber[b]=0;
        }

        for(int c=2;c<13;c++){
            int e=primenumber[c];
            if(e>0){
                for(int f=c+1;f<13;f++){
                    int g=primenumber[f];
                    if((g>0)&(g%e==0)){
                        primenumber[f]=0;
                    }


                }
            }
        }
    }


    for(int j=0;j<13;j++){
        System.out.println(primenumber[j]);
    }
     }

 }

答案 9 :(得分:0)

查看我的代码:

import java.util.Scanner;

public class c4 {

        public static void main(String[] args) {
            Scanner sn = new Scanner(System.in);

            System.out.println("Enter number");

            int num = sn.nextInt();

            if (num==1){
                System.out.println("Nor Prime Neither Composite");
            }
            for (int i=2;i<num;i++){
                int n=num%i;

                if (n==0){
                    System.out.println("It is a composite number");
                    break;
                }
               else{
                   System.out.println("it is a prime number");
                   break;
               }
           }
       }
    }

答案 10 :(得分:0)

这是我的解决方案。

public class PrimeNumberGenerator {

public static void print(int n) {
    // since 1 is not prime number.
    for (int i = 2; i <= n; i++) {
        if (isPrime(i)) {
            System.out.print(i + "\n");
        }
    }

}

public static boolean isPrime(int num) {

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

    return true;
}

public static void main(String[] args) {
    print(10);
  }

}

输出:2 3 五 7

答案 11 :(得分:0)

在您的情况下,对每个数字进行素数检查效率很低。改用Sieve_of_Eratosthenes,查找不超过任何给定限制的所有质数。

{
 "disabled": false,
 "bindings": [
  {
   "authLevel": "anonymous",
   "type": "httpTrigger",
   "direction": "in",
   "name": "req",
   "methods": [
    "get"
   ]
  },
  {
   "type": "http",
   "direction": "out",
   "name": "res"
  }
 ],
 "scriptFile": "../.funcpack/index.js",
 "entryPoint": "HttpTrigger1"
}

实施Eratosthenes筛时的优化技巧:

  • 仅对奇数进行迭代。因为2的所有倍数,除了2都是复合的。

  • 开始从public class PrimeGenerator { private final BitSet primes; private int nextPrime = 0; /** * Sieve of Eratosthenes */ public PrimeGenerator(final int LIMIT) { primes = new BitSet(LIMIT+1); primes.set(2, LIMIT); for (int i = 4; i < LIMIT; i += 2) primes.clear(i); final int SQRT = (int) Math.sqrt(LIMIT); for (int p = 3; p <= SQRT; p = primes.nextSetBit(p+2)) { for (int j = p * p; j <= LIMIT; j += 2 * p) { primes.clear(j); } } } public int nextPrime() { nextPrime = primes.nextSetBit(nextPrime + 1); return nextPrime; } public static void main(String[] args) { // print primes up to 1000 PrimeGenerator primeGen = new PrimeGenerator(50); int prime = primeGen.nextPrime(); while (prime != -1) { System.out.println(prime); prime = primeGen.nextPrime(); } } } 中删除。因此,例如对于素数3,您应该从9开始消除。

  • 增加(p * p)而不是p,以避免偶数。

这可以在几秒钟内生成数百万个素数。

答案 12 :(得分:0)

我在生成器中使用这种方式,效果很好。

const isPrime = (number) => {
  if (
    Number.isNaN(number) ||
    !Number.isFinite(number) ||
    number % 1 || //  check int number
    number < 2
  ) {
    return false;
  }
  let i = 2;
  const m = Math.ceil(Math.sqrt(number));
  let isPrime = true;
  while (i <= m) {
    if (number % i === 0) {
      isPrime = false;
      break;
    }
    i = i + 1;
  }
  return isPrime;
};

function* primeNumber() {
  let nextNumber = 2;
  while (true) {
    if (isPrime(nextNumber)) {
      yield nextNumber;
    }
    ++nextNumber;
  }
}

const iter = primeNumber();
for (const n of iter) {
  if (n > 100) iter.return("end");//end loop
  console.log(n);
}

您可以拨打电话以按顺序获取素数。

const iter = primeNumber();
console.log(iter.next())
console.log(iter.next())

在您的班级中加入thoes函数。

答案 13 :(得分:0)

我编写了此函数,其中列出了前n个素数:

static void primes(int n) {
    int[] prime = new int[n];
    prime[0] = 2;
    int pp = 0;

    int i = 2;
    while(pp < n - 1) {
        int g = 1;
        for(int p = 0; p <= pp; p++) {
            if(i % prime[p] == 0) {
                g = prime[p];
                break;
            }
        }
        if(g == 1) {
            pp += 1;
            prime[pp] = i;
        }
        i += 1;
    }
    
    for(int z = 0; z < n; z++) {
        System.out.println(prime[z]);
    }
}

它也应该相对较快,因为它检查了最低数量的必要除数。 (我认为)

答案 14 :(得分:-2)

package test;

import java.util.Scanner;

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner reader = new Scanner(System.in);  // Reading from System.in
        System.out.println("Please Enter number you wanted prime number to be generated");
        int n = reader.nextInt();
        reader.close();

        Prime t1 = new Prime();
        for (int i = 2; i <= n; i++) {
            t1.x(i);
        }
    }

    public void x(int n) {
        // TODO Auto-generated method stub
        // TODO Auto-generated constructor stub
        int k = n - 1;
        int f = 0;
        if (n == 2) {
            f = 1;
        }
        for (int i = 2; i <= k; i++) {
            if (n % i == 0)
                break;
            else if (k == i) {
                f = 1;
            }
        }
        if (f == 1) {
            System.out.println("is prime" + n);
        }

    }
}