【发布时间】:2015-06-07 09:34:32
【问题描述】:
嗯,在 SO 和其他论坛中有很多这样的问题。然而,这些都没有帮助。
我用“C”写了一个程序来查找一个范围内的素数。范围 i in long int。我正在使用Sieve of Eratosthenes" 算法。我正在使用一个长整数数组来存储从 1 到极限的所有数字。如果不使用数组,我想不出更好的方法来实现。该代码工作正常,直到 10000000。但在那之后,它耗尽了内存并退出。下面是我的代码。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned long uint_32;
int main() {
uint_32 i, N, *list, cross=0, j=4, k, primes_cnt = 0;
clock_t start, end;
double exec_time;
system("cls");
printf("Enter N\n");
scanf("%lu", &N);
list = (uint_32 *) malloc( (N+1) * sizeof(uint_32));
start = clock();
for(i=0; i<=N+1; i++) {
list[i] = i;
}
for(i=0; cross<=N/2; i++) {
if(i == 0)
cross = 2;
else if(i == 1)
cross = 3;
else {
for(j=cross+1; j<=N; j++) {
if(list[j] != 0){
cross = list[j];
break;
}
}
}
for(k=cross*2; k<=N; k+=cross) {
if(k <= N)
list[k] = 0;
}
}
for(i=2; i<=N; i++) {
if(list[i] == 0)
continue;
else
primes_cnt++;
}
printf("%lu", primes_cnt);
end = clock();
exec_time = (double) (end-start);
printf("\n%f", exec_time);
return 0;
}
我被困住了,想不出更好的方法来实现这一点。任何帮助将不胜感激。谢谢。
编辑:
我的目标是生成并打印范围以下的所有素数。由于打印耗费了大量时间,我想到了正确迈出第一步。
【问题讨论】:
-
对于初学者,您可以将数组用作位集(回想一下,您实际上需要它来判断真/假,而不是 2^32 值)。通过为数字分配一个位,它将为您提供 X32 更多可以存储的元素。 (对于 2^64 值仍然不够)。
-
感谢您的回复。我实际上需要打印范围以下的所有素数。但由于打印需要很多时间,我想先让我数一下总素数。如果我做对了,下一步会更容易。还有其他线索吗?
-
即使有一个位字段,你仍然可以得到数字。
-
您在问题中说过要生成范围内的素数。而到目前为止您的代码显示您正在生成从零到 n 的素数。对吗?
-
请注意,对于 Eratosthenes 算法的每次迭代,您从 n*n 而不是 n*2 开始消除。例如:要消除 2 的倍数,您从 2*2=4、6、8 ...开始,对于 3,您从 3*3=9、12、15....开始,对于 5,您从 5*5 开始=25,30,35,40...