eratosthenes筛的改进,时间和空间复杂性检查

时间:2015-03-04 14:47:48

标签: java time-complexity primes sieve-of-eratosthenes space-complexity

我理解'eratosthenes'算法的时间复杂度为O(n log log n)。我修改了这个算法,这样我的筛子总是大小为100.如果我找不到下一个素数,我将继续循环接下来的100个数字。我如何解释time-complexity Space complexitygetNthPrime方法的getNextPrimepublic class PrimeUtil { private static final boolean COMPOSITE = true; private static final int DEFAULT_SIZE = 100; // cache of primes. public final List<Integer> primes; public int cachedMaxPrime; public PrimeUtil() { primes = new ArrayList<Integer>(); // initial seed primes.addAll(Arrays.asList(2, 3, 5, 7, 11, 13)); cachedMaxPrime = primes.get(primes.size() - 1); } private void validate(int n) { if (n <= 0) { throw new IllegalArgumentException("Expecting a non-zero value"); } } public synchronized int getNthPrime(int nThPrime) { validate(nThPrime); if (nThPrime <= primes.size()) { return primes.get(nThPrime - 1); } int n = DEFAULT_SIZE; // find all primes for next 100 numbers. while (primes.size() < nThPrime) { computePrimesUptoN(n); n += DEFAULT_SIZE; // find all primts for next 100 numbers. } return primes.get(nThPrime - 1); } public synchronized int getNextPrime(int prime) { validate(prime); int primeIndex = Collections.binarySearch(primes, prime); if (primeIndex != -1 && primeIndex != (primes.size() - 1)) { return primes.get(primeIndex + 1); } int prevSize = primes.size(); int n = DEFAULT_SIZE; // adding cachedMaxPrime to DEFAULT_SIZE is a tiny optimization, nothing else. while (primes.size() == prevSize) { computePrimesUptoN(n); n += DEFAULT_SIZE; } return primes.get(primeIndex + 1); } private List<Integer> computePrimesUptoN(int n) { boolean[] composites = new boolean[n - cachedMaxPrime]; // int root = (int)Math.sqrt(n); // root is sqrt(50) ie 7. for (int i = 1; i < primes.size() && primes.get(i) <= root; i++) { // will loop until prime = 7. int prime = primes.get(i); // first prime: 3 int firstPrimeMultiple = (cachedMaxPrime + prime) - ((cachedMaxPrime + prime) % prime); if (firstPrimeMultiple % 2 == 0) { firstPrimeMultiple += prime; } filterComposites(composites, prime, firstPrimeMultiple, n); } // loop through all primes in the range of max-cached-primes upto root. for (int prime = cachedMaxPrime + 2; prime < root; prime = prime + 2) { if (!composites[prime]) { // selecting all the prime numbers. filterComposites(composites, prime, prime, n); } } for (int i = 1; i < composites.length; i = i + 2) { if (!composites[i]) { primes.add(i + (cachedMaxPrime + 1)); } } cachedMaxPrime = primes.get(primes.size() - 1); return primes; } private void filterComposites(boolean[] composites, int prime, int firstMultiple, int n) { for (int multiple = firstMultiple; multiple < n; multiple += prime + prime) { composites[multiple - (cachedMaxPrime + 1)] = COMPOSITE; } } }

摘录:

{{1}}

0 个答案:

没有答案