All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.math.prime.PrimeGenerator Maven / Gradle / Ivy

There is a newer version: 1.7.2
Show 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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy