我正在编写这个Java程序,它找到给定范围之间的所有素数。因为我正在处理非常大的数字,我的代码似乎不够快,并给我一个时间错误。这是我的代码,有谁知道让它更快?感谢。
import java.util.*;
public class primes2
{
private static Scanner streamReader = new Scanner(System.in);
public static void main(String[] args)
{
int xrange = streamReader.nextInt();
int zrange = streamReader.nextInt();
for (int checks = xrange; checks <= zrange; checks++)
{
boolean[] checkForPrime = Primes(1000000);
if (checkForPrime[checks])
{
System.out.println(checks);
}
}
}
public static boolean[] Primes(int n)
{
boolean[] isPrime = new boolean[n + 1];
if (n >= 2)
isPrime[2] = true;
for (int i = 3; i <= n; i += 2)
isPrime[i] = true;
for (int i = 3, end = sqrt(n); i <= end; i += 2)
{
if (isPrime[i])
{
for (int j = i * 3; j <= n; j += i << 1)
isPrime[j] = false;
}
}
return isPrime;
}
public static int sqrt(int x)
{
int y = 0;
for (int i = 15; i >= 0; i--)
{
y |= 1 << i;
if (y > 46340 || y * y > x)
y ^= 1 << i;
}
return y;
}
}
答案 0 :(得分:7)
只需更改此内容即可获得巨大的改进:
for (int checks = xrange; checks <= zrange; checks++)
{
boolean[] checkForPrime = Primes(1000000);
到此:
boolean[] checkForPrime = Primes(1000000);
for (int checks = xrange; checks <= zrange; checks++)
{
您当前的代码会重新生成筛子zrange - xrange + 1
次,但实际上您只需要生成一次。
答案 1 :(得分:0)
显而易见的问题是你多次计算质量达到1000000(zrange - xrange次)。另一个是你不需要计算高达1000000的素数,你只需要检查素数到zrange,所以你在zrange&lt; 1000000,并在zrange&gt;时获得缓冲区溢出百万。
答案 2 :(得分:0)
您可以从i*i
开始内循环,即代替for (int j = i * 3; j <= n; j += i << 1)
,您可以编写for (int j = i * i; j <= n; j += i << 1)
以获得较小的加速。
此外,您必须确保zrange
不大于1000000
。
如果xrange
远大于sqrt(zrange)
,您还可以将筛阵列拆分为两个,用于偏移筛方案。较低的数组将从2到sqrt(zrange)
。较高的一个将从xrange
延伸到zrange
。当您筛选出较低的数组时,每个新的素数都会被它识别出来,在您的内部循环中,除了将较低的数组标记到其末端之外,还要筛选上部数组。您将必须计算每个素数i
的起始偏移量,并使用与2*i
相同的步骤,就像对下半部分一样。如果你的范围比几个素数更宽,你将获得速度优势(否则只需按赔率划分试验即可)。
另一件事是,如果evens > 2
不是素数,为什么要在阵列中代表它们并浪费一半的空间?您可以将每个i
视为代表奇数2*i+1
,从而压缩您的数组。
最后一个简单的技巧是通过标记ON
而不仅仅是odds
(即2
的复制品)来预先消除3 的倍数, { ... i+=2; ...}
仅2
,而3
只有{ ... i+=2; ... i+=4; ... }
和 OFF
的副本。此外,在标记> 3
倍数的{ ... j+=2*i; ... j+=4i; ...}
时,也请使用5*5, 5*7, 5*9, 5*11, ...
。例如,在OFF
中,如果5*9
的多个3
未标记为ON
,则无需标记{{1}} {{1}}。