普通的筛法就不多说了,今天动了点脑筋,对普通的筛法做了点常数优化,主要是利用素数除了2以外全是奇数,那偶数就能排除掉不用再管了,再进一步优化就是只需排除素数的所有奇数倍。时间复杂度好像是O(N+1/4logNlogN)?感觉好像不对啊,求指导。。。>_<
C语言代码:
//By LYLtim
#include<stdio.h>
#include<math.h>
int main(void) {
unsigned i, j, n = 100, n_sqrt = sqrt(n), sum = 0;
char isprime[n + 1];
//初始化数组,除了2以外,偶数肯定不是素数,素数肯定是奇数。
isprime[2] = 1;
for(i = 3; i < n; i++)
if (i & 1) //奇数
isprime[i] = 1;
else //偶数
isprime[i] = 0;
//初始化已排除偶数,然后只需排除所有素数(也只需从奇数里选)的所有奇数倍
for(i = 3; i < n_sqrt; i += 2)
if (isprime[i])
for(j = i * 3; j <= n; j += i<<1) //排除素数的所有奇数倍
isprime[j] = 0;
for(i = 2; i < n; i++)
if (isprime[i])
printf("%u ", i);
getchar();
}
Java代码:
//By LYLtim
public class Prime {
public static void main(String[] args) {
int n = 100, sqrt = (int) Math.sqrt(n), sum = 0;
boolean[] isPrime = new boolean[n + 1];
//初始化数组,除了2以外,偶数肯定不是素数,素数肯定是奇数。
isPrime[2] = true;
for (int i = 3; i < n; i += 2)
isPrime[i] = true;
for (int i = 3; i < sqrt; i += 2)
if (isPrime[i]) //从奇数中选出素数
for (int j = i * 3; j <= n; j += i<<1) //排除素数的所有奇数倍
isPrime[j] = false;
for (int i = 2; i < n; i++)
if (isPrime[i])
System.out.print(i + " ");
}
}
以N=100为例,打印出100以内的素数:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97