Finding prime numbers with the Sieve of Eratosthenes (Originally: Is there a better way to prepare this array?)

前端 未结 13 1486
攒了一身酷
攒了一身酷 2020-12-02 23:38

Note: Version 2, below, uses the Sieve of Eratosthenes. There are several answers that helped with what I originally asked. I have chosen the Sieve of Era

相关标签:
13条回答
  • 2020-12-03 00:15

    Not sure if this will suite your situation but you can take a look at my approach. I used mine using Sieve of Eratosthenes.

      public static List<Integer> sieves(int n) {
            Map<Integer,Boolean> numbers = new LinkedHashMap<>();
    
            List<Integer> primes = new ArrayList<>();
    
            //First generate a list of integers from 2 to 30
            for(int i=2; i<n;i++){
                numbers.put(i,true);
            }
    
            for(int i : numbers.keySet()){
                /**
                 * The first number in the list is 2; cross out every 2nd number in the list after 2 by 
                 * counting up from 2 in increments of 2 (these will be all the multiples of 2 in the list):
                 * 
                 * The next number in the list after 2 is 3; cross out every 3rd number in the list after 3 by 
                 * counting up from 3 in increments of 3 (these will be all the multiples of 3 in the list):
                 * The next number not yet crossed out in the list after 5 is 7; the next step would be to cross out every
                 * 7th number in the list after 7, but they are all already crossed out at this point,
                 * as these numbers (14, 21, 28) are also multiples of smaller primes because 7 × 7 is greater than 30. 
                 * The numbers not crossed out at this point in the list are all the prime numbers below 30:
                 */
                if(numbers.get(i)){
                    for(int j = i+i; j<n; j+=i) {
                        numbers.put(j,false);
                    }
                }
            }
    
    
            for(int i : numbers.keySet()){
                for(int j = i+i; j<n && numbers.get(i); j+=i) {
                    numbers.put(j,false);
                }
            }
    
            for(int i : numbers.keySet()){
               if(numbers.get(i)) {
                   primes.add(i);
               }
            }
            return primes;
        }
    

    Added comment for each steps that has been illustrated in wikipedia

    0 讨论(0)
  • 2020-12-03 00:16

    Algo using Sieve of Eratosthenes

    public static List<Integer> findPrimes(int limit) {
    
        List<Integer> list = new ArrayList<>();
    
        boolean [] isComposite = new boolean [limit + 1]; // limit + 1 because we won't use '0'th index of the array
        isComposite[1] = true;
    
        // Mark all composite numbers
        for (int i = 2; i <= limit; i++) {
            if (!isComposite[i]) {
                // 'i' is a prime number
                list.add(i);
                int multiple = 2;
                while (i * multiple <= limit) {
                    isComposite [i * multiple] = true;
                    multiple++;
                }
            }
        }
    
        return list;
    }
    

    Image depicting the above algo (Grey color cells represent prime number. Since we consider all numbers as prime numbers intially, the whole is grid is grey initially.)

    enter image description here

    Image Source: WikiMedia

    0 讨论(0)
  • 2020-12-03 00:19

    I have done using HashMap and found it very simple

    import java.util.HashMap;
    import java.util.Map;
    
    /*Using Algorithms such as sieve of Eratosthanas */
    
    public class PrimeNumber {
    
        public static void main(String[] args) {
    
            int prime = 15;
            HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
    
            hashMap.put(0, 0);
            hashMap.put(1, 0);
            for (int i = 2; i <= prime; i++) {
    
                hashMap.put(i, 1);// Assuming all numbers are prime
            }
    
            printPrimeNumberEratoshanas(hashMap, prime);
    
        }
    
        private static void printPrimeNumberEratoshanas(HashMap<Integer, Integer> hashMap, int prime) {
    
            System.out.println("Printing prime numbers upto" + prime + ".....");
            for (Map.Entry<Integer, Integer> entry : hashMap.entrySet()) {
                if (entry.getValue().equals(1)) {
                    System.out.println(entry.getKey());
                    for (int j = entry.getKey(); j < prime; j++) {
                        for (int k = j; k * j <= prime; k++) {
                            hashMap.put(j * k, 0);
                        }
                    }
    
                }
            }
    
        }
    
    }
    

    Think this is effective

    0 讨论(0)
  • 2020-12-03 00:20

    As Paul Tomblin points out, there are better algorithms.

    But keeping with what you have, and assuming an object per result is too big:

    You are only ever appending to the array. So, use a relatively small int[] array. When it's full use append it to a List and create a replacement. At the end copy it into a correctly sized array.

    Alternatively, guess the size of the int[] array. If it is too small, replace by an int[] with a size a fraction larger than the current array size. The performance overhead of this will remain proportional to the size. (This was discussed briefly in a recent stackoverflow podcast.)

    0 讨论(0)
  • 2020-12-03 00:21
    public static void primes(int n) {
            boolean[] lista = new boolean[n+1];
            for (int i=2;i<lista.length;i++) {
                if (lista[i]==false) {
                    System.out.print(i + " ");
                }
                for (int j=i+i;j<lista.length;j+=i) {
                    lista[j]=true;
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-03 00:22

    Your method of finding primes, by comparing every single element of the array with every possible factor is hideously inefficient. You can improve it immensely by doing a Sieve of Eratosthenes over the entire array at once. Besides doing far fewer comparisons, it also uses addition rather than division. Division is way slower.

    0 讨论(0)
提交回复
热议问题