我理解'eratosthenes'算法的时间复杂度为O(n log log n)。我修改了这个算法,这样我的筛子总是大小为100.如果我找不到下一个素数,我将继续循环接下来的100个数字。我如何解释time-complexity
Space complexity
和getNthPrime
方法的getNextPrime
和public 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}}