时间:2021-07-01 10:21:17 帮助过:79人阅读
#include
#include
#include
#include
#define PRIME_LIM 10000000
#define N 100000000
int primes[PRIME_LIM] = {0};
int flags[N/96 + 1] = {0};
int get_prime()
{
int nu = 5, to = 0;
primes[0] = 2;
primes[1] = 2, primes[2] = 3;
for(int i = 0; nu <= N; i++) {
if(!(flags[i>>5]&(1<<(i&31)))) primes[++primes[0]] = nu;
for(int j = 3; j <= primes[0] && primes[j] * nu <= N; j++) {
to = (nu * primes[j] - 5) >> 1;
to -= to/3;
flags[to>>5] |= 1<<(to&31);
if(!(nu % primes[j])) break;
}
nu += 2 + ((i&1) << 1);
}
return primes[0];
}
int main()
{
clock_t t = clock();
printf("%d\n", get_prime());
printf("Time:%f\n", 1.0 * (clock() - t) / CLOCKS_PER_SEC);
for(int i = 1; primes[i] < 100; i++) {
printf("%d\n", primes[i]);
}
return 0;
}
【多种方法比较,长文慎入】class Prime{
public static int calculateNumber(int Nmax){
boolean[] isPrime=new boolean[Nmax+1];
for(int i=3;i<=Nmax;i+=2)
isPrime[i]=true;
isPrime[2]=true;
for(int i=3;i<=Math.sqrt(Nmax);i+=2){
if(isPrime[i]==true){
for(int j=i*i;j<=Nmax;j+=2*i)
isPrime[j]=false;
}
}
int primeNum=0;
for(int i=1;i<=Nmax;i++){
if(isPrime[i]==true)
primeNum++;
}
return primeNum;
}
public static void main(String[] args){
final int Nmax=2000000;
double startTime=System.currentTimeMillis();
int primeNum=Prime.calculateNumber(Nmax);
double timeSpent=(System.currentTimeMillis()-startTime)/1000;
System.out.println("The prime numbers from 1 to "+Nmax+" is "+primeNum);
System.out.println("Time spent : "+timeSpent+" s");
}
}
如果题主希望得到的答案仅限于筛法,那基本上线性筛从复杂度上已经是最优的了,只剩下各种优化了。特别是如果要死扣最后那么点性能,就必然是面向体系结构的优化了,比如多线程优化、根据intel的体系结构如何选择各类指令的分布、用类似prefetch之类的指令降低存储器访问延迟等等。#include
#include
#include
#include
const int N = 2000000;
bool b[N+1];
int c[N+1];
void Era_select(){ // Eratosthenes
memset(b, 0, N+1);
int q = (int)sqrt(N);
int i, j, cnt = 0;
for ( i=2; i<=q; ++i ){
if ( ! b[i] ){
for ( j=i<<1; j<=N; j+=i ){
b[j] = true;
}
}
}
for ( i=2; i<=N; ++i ){
if ( ! b[i] ){
++cnt;
}
}
//printf("%d\n", cnt);
}
void Euler_select(){
memset(b, 0, N+1);
int i, j, cnt = 0, t;
for ( i=2; i<=N; ++i ){
if ( ! b[i] ){
c[cnt++] = i;
}
for ( j=0; j<cnt; ++j ){
t = i*c[j];
if ( t > N ){
break;
}
b[t] = true;
if ( i%c[j] == 0 ){
break;
}
}
}
//printf("%d\n", cnt);
}
int main(){
int i, num=100;
clock_t start;
start = clock();
for ( i=0; i<num; ++i ){
Era_select();
}
printf("%lf seconds\n", (double)(clock()-start) / CLOCKS_PER_SEC / num);
start = clock();
for ( i=0; i<num; ++i ){
Euler_select();
}
printf("%lf seconds\n", (double)(clock()-start) / CLOCKS_PER_SEC / num);
return 0;
}
stackoverflow上有个关于用python求解最快算法的讨论(optimization),如果用纯python语言的话,最快的算法是下面这个:def rwh_primes2(n = 10**6):
# http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Input n>=6, Returns a list of primes, 2 <= p < n """
correction = (n%6>1)
n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]
sieve = [True] * (n/3)
sieve[0] = False
for i in xrange(int(n**0.5)/3+1):
if sieve[i]:
k=3*i+1|1
sieve[ ((k*k)/3) ::2*k]=[False]*((n/6-(k*k)/6-1)/k+1)
sieve[(k*k+4*k-2*k*(i&1))/3::2*k]=[False]*((n/6-(k*k+4*k-2*k*(i&1))/6-1)/k+1)
return [2,3] + [3*i+1|1 for i in xrange(1,n/3-correction) if sieve[i]]
很多人说我是喷子,我不同意以前为了算某个群号,曾经计算了八千万以内的素数,花了两秒钟。群里有个人0.2秒,觉得很牛逼,始终没明白是怎么做的。
我的做法很简单,给出八千万个bool(其实可以去掉偶数)。一开始拿出2,把2的倍数都true了。下一个false的是3,把3的倍数都true了。下一个false的是5,把5的倍数都true了。一只做到完。