这是我查找第10000个素数的代码,但它真的很慢,计算需要7秒。
#include <stdio.h>
#include <stdlib.h>
long int prime (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int i=2,counter=0;
while(1)
{
if(prime(i))
counter++;
if(counter==10000)
break;
i++;
}
printf("10000th prime number is: %d",i);
}
这是蛮力方法,所以这可能是为什么它如此缓慢的原因。 我认为问题可能是它必须多次调用函数。那么你认为它可以被优化,或者最好为此找到一些数学公式。
答案 0 :(得分:0)
稍微优化您的代码(根据评论进行更改):
long int prime (int n)
{
int i;
int e = (int)sqrt(n);
for(i=2; i<=e;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
答案 1 :(得分:0)
您可以通过对prime()
进行以下更改来大幅减少时间:
sqrt(n)
。i=3
开始,i
增加2
。这是一个包含两个版本和每个版本所用时间的程序。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
int is_prime1 (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it1(int max)
{
clock_t start = clock();
clock_t end;
int i=2,counter=0;
while(1)
{
if(is_prime1(i))
counter++;
if(counter==max)
break;
i++;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int is_prime2 (int n)
{
int i;
int stop = sqrt(n);
for(i=3;i<=stop;i+=2)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it2(int max)
{
clock_t start = clock();
clock_t end;
int i=3,counter=1;
while(1)
{
if(is_prime2(i))
counter++;
if(counter==max)
break;
i += 2;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int main(int argc, char** argv)
{
int max = atoi(argv[1]);
do_it1(max);
do_it2(max);
}
示例执行:
./test 10000
示例输出:
10000th prime number is: 104729
Time taken: 9.469000
10000th prime number is: 104729
Time taken: 0.078000
答案 2 :(得分:-1)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int *prime;
int prime_n;
void make_prime_table(int n){
prime = malloc(sizeof(int) * n / 2);
prime_n =0;
prime[prime_n++] = 2;
prime[prime_n++] = 3;
int i, j;
for(i = 5; i <= n; i +=2){
bool is_prime = true;
for(j = 1; j < prime_n ; ++j){
int t = prime[j];
if(t * t > i)
break;
if(i % t == 0){
is_prime = false;
break;
}
}
if(is_prime)
prime[prime_n++] = i;
}
}
int main(void){
int n = 105000;
make_prime_table(n);
if(prime_n >= 10000)
printf("10000th prime number is: %d\n", prime[9999]);
free(prime);
return 0;
}