我已经看到了一些与争论有关的问题,但是一旦没有人完全符合我的要求,我就会制作一个新的。我必须计算前N个素数(示例中为1000)。我推出了一个工作正常的算法,但它根本没有优化。
#include<stdio.h>
#define MAX_NUMBERS 1000
int main()
{
int prime[MAX_NUMBERS]={0};
int filled=0;
prime[filled++]=2;
int n=0,i=0;
while(filled<MAX_NUMBERS) {
for( n=prime[filled-1]+1; ;n++ ) {
int found =0;
for( i=0; i<filled && (found==0); i++ ) {
if( (n%prime[i]) == 0 ) {
found = 1;
}
}
if( !found ) {
break;
}
}
/* we know that this always exists */
prime[filled++]=n;
}
for(i=0;i<filled;i++) {
printf( "prime number %d\n", prime[i] );
}
return 0;
}
有人知道如何优化它吗?在这种情况下,是否有任何算法更改可以提供帮助?
答案 0 :(得分:1)
int found =0;
for( i=0; i<filled && (found==0); i++ ) {
if( (n%prime[i]) == 0 ) {
found = 1;
}
}
if( !found ) {
break;
}
将其更改为:
int found =0;
for( i=0; i < filled && prime[i]*prime[i]<=n; i++ ) {
if( (n%prime[i]) == 0 ) {
found = 1;
break;
}
}
if( !found ) {
break;
}
答案 1 :(得分:1)
最好的方法是通过筛选方法,如下所述,最简单,最有效:
答案 2 :(得分:0)
您可以通过执行
来减少循环次数for( i = 0; prime[i] <= sqrt(n); i++ ) {...}
我使用了sqrt(filled)
,因为您不需要检查大于其方格的数字,以了解它是否可被任何小于它的数字(不包括1
)整除。 (别忘了包括`header)
答案 3 :(得分:0)
如果需要减少执行的循环次数,可以在源代码中存储小素数表。
另一个小优化基于以下事实:大于3的素数都是6k-1或6k + 1的形式。因此,不是每六个中检查三个奇数,而是仅检查两个是否具有素数。
然而,找到素数的更好方法是使用上面提到的某种筛子: Sieve of Eratosthenes,Sieve of Atkin,Sieve of Sundaram。