我一直在Sphere Online Judge(SPOJ)上做一些挑战,但我似乎无法在时间限制内运行the second problem(素数生成器)。如何提高以下代码的速度?
#include <stdio.h>
#include <math.h>
int is_prime(int n);
void make_sieve();
void fast_prime(int n);
int primes[16000];
int main()
{
int nlines;
int m, n;
make_sieve();
scanf("%d", &nlines);
for (; nlines >= 1; nlines--) {
scanf("%d %d", &m, &n);
if (!(m % 2)) {
m++;
}
for ( ; m < n; m+=2) {
fast_prime(m);
}
printf("\n");
}
return 0;
}
/* Prints a number if it's prime. */
inline void fast_prime(int n)
{
int j;
for (int i = 0; ((j = primes[i]) > -1); i++) {
if (!(n % j)) {
return;
}
}
printf("%d\n", n);
}
/* Create an array listing prime numbers. */
void make_sieve()
{
int j = 0;
for (int i = 0; i < 16000; i++) {
primes[i] = -1;
}
for (int i = 2; i < 32000; i++) {
if (i % 2) {
if (is_prime(i)) {
primes[j] = i;
j++;
}
}
}
return;
}
/* Test if a number is prime. Return 1 if prime. Return 0 if not. */
int is_prime(int n)
{
int rootofn;
rootofn = sqrt(n);
if ((n <= 2) || (n == 3) || (n == 5) || (n == 7)) {
return 1;
}
if (((n % 2) == 0) || ((n % 3) == 0) || ((n % 5) == 0) || ((n % 7) == 0)) {
return 0;
}
for (int i = 11; i < rootofn; i += 2) {
if ((n % i) == 0) {
return 0;
}
}
return 1;
}
答案 0 :(得分:2)
isprime()不使用素数表primes []。
另外,实现搜索将使用二进制搜索算法快速完成的素数数组。标准库有一个。
要查看您在代码中花费的时间,可以使用分析 gcc示例
gcc -p -g - o mycode mycode.c
===run the code--
gprof mycode
答案 1 :(得分:1)
目前,您的问题不是时间限制。事实上你的程序从不打印任何数字。
最明显的错误是你在fast_prime中检查n是否可以被prime [0],prime [1],...归为prime [k]。即使n是素数,你也不会打印它,因为n在primes []的某个地方,所以你会得到n可以被某个数字整除...
要纠正这个问题,你需要检查n是否可以被一些素数整除,直到n的平方根(这也会产生加速代码的副作用,因为在确定一些数字之前会检查更少的数字)是一个素数)
将fast_prime更改为
inline void fast_prime(int n)
{
int j;
int rootofn;
rootofn = sqrt(n);
for (int i = 0; ((j = primes[i]) > -1) && (j<rootofn); i++) {
if (!(n % j)) {
return;
}
}
printf("%d\n", n);
}