要生成Prime到N,我正在使用此代码。
private static void primePrint(int n) {
int sum=0;
int maxFactor= (int)Math.sqrt(n);
boolean[] isPrime=new boolean[n + 1];
int len=isPrime.length;
Arrays.fill(isPrime,true);
isPrime[0]=false;
isPrime[1]=false;
for(int i=0;i<=maxFactor;i++){
if(isPrime[i]){
for(int j=i+i;j<len;j+=i){
isPrime[j]=false;
}
}
}
for(int i=2;i<=n;i++){
if(isPrime[i]){
System.out.println(i)
}
}
}
但是最近有人建议我减半我的maxfactor并使用这个循环因为它提高了效率。但我无法弄清楚它是如何运作的。
maxFactor = maxFactor/2 - 1;
boolean[] isPrime = new boolean[n/2+1];
for(int i = 0; i < maxFactor; ++i) {
if (!isPrime[i]) {
for(int j = 2*i*(i+3)+3, p = 2*i+3; j < n/2; j += p) {
isPrime[j] = true;
}
如果有人能够对此有所了解,那将会有很大的帮助。
编辑:使用此
生成nthPrime的工作代码class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
System.out.println(nthPrime(25));
}
public static int nthPrime(int n) {
if (n < 2) return 2;
if (n == 2) return 3;
int limit, root, count = 1;
limit = (int)(n*(Math.log(n) + Math.log(Math.log(n)))) + 3;
root = (int)Math.sqrt(limit) + 1;
limit = (limit-1)/2;
root = root/2 - 1;
boolean[] sieve = new boolean[limit];
for(int i = 0; i < root; ++i) {
if (!sieve[i]) {
++count;
for(int j = 2*i*(i+3)+3, p = 2*i+3; j < limit; j += p) {
sieve[j] = true;
}
}
}
int p;
for(p = root; count < n; ++p) {
if (!sieve[p]) {
++count;
}
}
return 2*p+1;
}
}
答案 0 :(得分:1)
但是最近有人建议我将我的maxfactor减半并使用这个循环,因为它会提高效率。
我怀疑那个&#34;某人&#34;是错的。 (也许他们在戏弄你......)
maxFactor == sqrt(N)背后的原因是:
但是,如果使maxFactor小于sqrt(N),则可能不会删除一个或多个非素数。换句话说,你在筛子上打了一个洞。
你修改过的版本中的内循环对我来说毫无意义......作为Eratosthenes筛选的实现。
事实上,根据您提供的链接中的代码,我认为这是Sieve of Sundaram(而不是您标记的Eratosthenes的Sieve。)我还会注意到该链接的代码正在解决一个不同的问题:找到第N个素数(并非所有质数都小于或等于N)。
无论如何,我的回答是,作为你关于实施Eratosthenes筛选的问题的答案。
(如果你想要解决Sundaram的筛子......你已经拥有它了。)
答案 1 :(得分:0)
我认为你不能让这项工作产生素数。为了证明你的朋友没有找到一个很好的新方法来生成素数我提交: j = 2 * i *(i + 3)+3 是什么分配素数但是当你到达i = 1然后j = 11并且我们还没有指定5作为素数。由于我认为算法无法返回,我们错过了一个素数。
同样isPrime被初始化为n / 2 + 1大小,所以我们甚至没有空间来收集我们正在寻找的数据。