常数优化的筛法求N以内素数表(附C语言、Java代码)
普通的筛法就不多说了,今天动了点脑筋,对普通的筛法做了点常数优化,主要是利用素数除了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代码:
1 //By LYLtim 2 public class Prime { 3 public static void main(String[] args) { 4 int n = 100, sqrt = (int) Math.sqrt(n), sum = 0; 5 boolean[] isPrime = new boolean[n + 1]; 6 //初始化数组,除了2以外,偶数肯定不是素数,素数肯定是奇数。 7 isPrime[2] = true; 8 for (int i = 3; i < n; i += 2) 9 isPrime[i] = true; 10 for (int i = 3; i < sqrt; i += 2) 11 if (isPrime[i]) //从奇数中选出素数 12 for (int j = i * 3; j <= n; j += i<<1) //排除素数的所有奇数倍 13 isPrime[j] = false; 14 for (int i = 2; i < n; i++) 15 if (isPrime[i]) 16 System.out.print(i + " "); 17 } 18 }
以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