对于非常大的第n个项,计算素数之和的程序非常慢。请问如何优化程序的处理时间?最快的程序将受到赞赏,以及我的大型数据集的速度慢的原因。感谢。
这是Java程序:
public class SumOfPrimes {
public static void main(String[] args) {
primeNumber(2000000);
}
public static void primeNumber(int nth) {
int counter = 0, i = 2;
while(i>=2) {
if(isPrime(i)) {
counter += i;
}
i++;
if(i == nth) {
break;
}
}
System.out.println(counter);
}
public static boolean isPrime(int n) {
boolean prime = true;
int i;
for(i= 2; i < n; i++) {
if (n % i == 0) {
prime = false;
for (int j = 3; j * j < n; j += 2) {
if (n % j == 0) prime = false;
}
}
}
return prime;
}
}
答案 0 :(得分:8)
嗯,目前还不清楚为什么你的isPrime
内有for循环。删除它将节省很多时间。
此外,一旦您发现n
不是素数,您应立即返回。要么突破循环,要么只返回false
。
另一个优化是在i < n
之前不测试所有数字。它足以测试到i * i <= n
。
public static boolean isPrime(int n) {
int i;
for(i = 2; i * i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
答案 1 :(得分:4)
记住你找到的素数,只测试它们。
删除内循环。
测试2,3,然后是所有赔率。
像...一样的东西。
public boolean isPrime( ArrayList<Long> primes, long n ){
for( Long t : primes ){
if( n % t == 0 ){
return false;
}
if( t * t > n )return true;
}
return true;
}
public void sumOfPrimes()
{
ArrayList<Long> primes = new ArrayList<Long>();
long n;
double count = 0;
for( n = 2; n < 2000000; n++ ){
if( isPrime( primes, n ) ){
primes.add( n );
count += n;
}
}
}
答案 2 :(得分:3)
这应该是你的isPrime功能 -
bool isPrime (int number) {
if (number < 2) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
for (int i=3; (i*i) <= number; i+=2) {
if (number % i == 0 ) return false;
}
return true;
}
答案 3 :(得分:0)
利用Lambda的强大功能进行动态功能参考和流,以通过内置过滤条件优化性能。
public static boolean isPrime(final int number) {
return IntStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0);
}
答案 4 :(得分:0)
将上述问题的所有答案汇总在一起,我的程序已经重新编写,对于非常大的数据集来说速度要快得多。
public class SumOfPrimes {
public static void main(String[] args) {
primeNumber(2000000);
}
public static void primeNumber(int nth) {
int i = 2;
long counter = 0;
while(i>=2) {
if(isPrime(i)) {
counter += i;
}
i++;
if(i == nth) {
break;
}
}
System.out.println(counter);
}
public static boolean isPrime (int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i=3; (i*i) <= n; i+=2) {
if (n % i == 0 ) return false;
}
return true;
}
}
@ aega的isPrime函数解决方案就行了。现在可以计算不到2秒的200万个数据集。
答案 5 :(得分:0)
我们不需要从1到n进行测试,甚至3到n / 2或3到sqrt(n)对于测试更大的数字也是太多了。
为了进行最少的测试,我们只能测试n之前已经找到的最高为sqrt(n)的素数,就像mksteve所提到的那样。
static List<Integer> primes = new ArrayList<>();
static boolean isPrime (int number) {
if (number < 2) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
int limit = (int) Math.sqrt(number);
for (i : primes) {
if (i > limit) break;
if (number % i == 0 ) return false;
}
return true;
}
public static void primeNumber(int nth) {
int i = 2;
long counter = 0;
while(i <= nth) {
if(isPrime(i)) {
counter += i;
primes.add(i);
}
i++;
}
System.out.println(counter);
}
答案 6 :(得分:0)
更快的程序是将生成的素数存储在数组中,并仅使用这些元素进行可分性检查。迭代次数将大幅减少。在这里有自学的元素。
我现在没有时间。但是,当我有空时,会写一个java代码来实现它。