我必须计算从0到N的区间中的素数的数量。问题是当N> 0时,程序运行得非常慢。 100000。
int main(){
long int i, j, n,isPrime;
long int N, count;
N = 10000000;
count = 0;
for(i = 2; i <= N; i++){
isPrime = 0;
for(j = 2; j <= i/2; j++){
if(i % j == 0){
isPrime = 1;
break;
}
}
if(isPrime==0 && N!= 1)
/*printf("%d ",i);*/
if(isPrime==0 && N!= 1)
count++;
}
printf(" %li ", count);
getch();
return 0;
}
答案 0 :(得分:4)
你不必前往i/2
寻找素数,只需仰望平方根。任何超过平方根的除数都没有用:你之前已经找到了它们的对应物。
int sqr = int(sqrt(i)); // make sure it is computed only once
for(j = 2; j <= sqr; j++){
应该这样做......
或(如建议的那样)比较正方形以避免计算所有
的sqrtfor(j = 2; j*j <= i; j++){
如果一个大数字是素数,那么该方法很有用。但要找到一系列素数,你最好使用Sieve of Erathostenes算法(我已经链接了C版本)。
答案 1 :(得分:2)
首先,这一行:
for(i = 2; i <= N; i++){
从i=2
开始,然后转到:
i=3
i=4
i=5
i=6
i=7
为什么要检查4,6和8之类的值?
您可以立即跳过这些值!
将您的行更改为:
for(i = 3; i <= N; i+=2){ /* Start at 3, then 5, 7, 9, 11, etc. */
答案 2 :(得分:0)
不要使用模数运算。用筛子。
static unsigned char sieve[10000000] = {0};
long countprimes(long N)
{
long answer = 0;
long i;
long j = 2;
long rootN = ceil(sqrt(N));
while(j < rootN)
{
for(i=j+j;i<N;i+=j)
sieve[i] = 1;
j++;
while(sieve[j])
j++;
}
for(i=2;i<N;i++)
if(!sieve[i])
answer++;
return answer;
}