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

前端 未结 13 1679
攒了一身酷
攒了一身酷 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:10

    I have a really efficient implementation:

    1. we don't keep the even numbers, therefore halving the memory usage.
    2. we use BitSet, requiring only one bit per number.
    3. we estimate the upper bound for number of primes on the interval, thus we can set the initialCapacity for the Array appropriately.
    4. we don't perform any kind of division in the loops.

    Here's the code:

    public ArrayList sieve(int n) {
        int upperBound = (int) (1.25506 * n / Math.log(n));
        ArrayList result = new ArrayList(upperBound);
        if (n >= 2)
            result.add(2);
    
        int size = (n - 1) / 2;
        BitSet bs = new BitSet(size);
    
        int i = 0;
        while (i < size) {
            int p = 3 + 2 * i;
            result.add(p);
    
            for (int j = i + p; j < size; j += p)
                bs.set(j);
    
            i = bs.nextClearBit(i + 1);
        }
    
        return result;
    }
    

提交回复
热议问题