com.github.azbh111.utils.java.math.prime.PrimeGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-java Show documentation
Show all versions of utils-java Show documentation
com.github.azbh111:utils-java
The newest version!
package com.github.azbh111.utils.java.math.prime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 质数生成器
*
* @author pyz
* @date 2019/4/14 5:34 PM
*/
public class PrimeGenerator implements Iterator {
private static final int[] staticPrimeCache = new int[]{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
// 2是用位运算进行判断的,也算作缓存,所以这里要+1
private static final int staticCacheSize = staticPrimeCache.length;
private static final int zeroCandidate;
private static final Skip skips;
static {
int grow;
if ((staticPrimeCache[staticPrimeCache.length - 1] - 1) % 3 == 0) {
grow = 4;
} else {
grow = 2;
}
zeroCandidate = staticPrimeCache[staticPrimeCache.length - 1];
skips = new Skip();
skips.skip = grow;
skips.next = new Skip();
skips.next.skip = 6 - grow;
skips.next.next = skips;
}
private Skip skip;
private int cacheSize;
private final List primeCache;
private int count = 0;
private int candidate;
/**
* 生成器会缓存一些质数(默认16个),用来加快质数判断速度
*
*/
public PrimeGenerator() {
this(16);
}
/**
* 生成器会缓存一些质数,用来加快质数判断速度
* cacheSize大小的缓存,可以大幅提升在(,cacheSize*cacheSize)范围内寻找质数的速度
*
* @param cacheSize 缓存大小
*/
public PrimeGenerator(int cacheSize) {
if (cacheSize < 0) {
throw new IllegalArgumentException(cacheSize + "");
}
this.cacheSize = cacheSize;
primeCache = new ArrayList<>(cacheSize);
candidate = zeroCandidate;
skip = skips;
}
@Override
public boolean hasNext() {
return true;
}
@Override
public Integer next() {
return nextInt();
}
/**
* 已经产生了多少个质数
* @return
*/
public int count() {
return count;
}
public int nextInt() {
if (count < staticCacheSize) {
return staticPrimeCache[count++];
}
candidate += skip.skip;
skip = skips.next;
while (!isPrime(candidate)) {
candidate += skip.skip;
skip = skips.next;
}
cache1(candidate);
count++;
return candidate;
}
private boolean isPrime(int number) {
if ((number & 1) == 0) {
return false;
}
int ratio = staticPrimeCache[1];
if ((number % ratio) == 0) {
return false;
}
int top = (int) Math.sqrt(number);
if (top * top == number) {
return false;
}
for (int i = 2; i < staticPrimeCache.length; i++) {
ratio = staticPrimeCache[i];
if (ratio > top) {
return true;
}
if (number % ratio == 0) {
return false;
}
}
// 走到这里 说明number大于 staticPrimeCache[staticPrimeCache.length-1] * staticPrimeCache[staticPrimeCache.length-1]
for (Integer integer : primeCache) {
ratio = integer.intValue();
if (ratio > top) {
return true;
}
if (number % integer.intValue() == 0) {
return false;
}
}
// 能走到这里,说明已经在缓存范围之外
ratio = primeCache.get(primeCache.size() - 1) + 2;
while (ratio <= top) {
if (number % ratio == 0) {
return false;
}
ratio += 2;
}
return true;
}
private void cache1(int prime) {
if (staticPrimeCache[staticCacheSize - 1] < prime && primeCache.size() < cacheSize) {
primeCache.add(prime);
}
}
private static class Skip {
private int skip;
private Skip next;
}
}