本文出自:blog.csdn.net/svitter
筛素数筛不到10000000
#include <iostream>
#include <cstdio>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
#define N 1000000//12031230
int digit[N]; //记录素因子
int num[N]; //记录每个素因子个数
int c; //记录素因子的个数
void divide(int n) {
memset(digit, 0, sizeof(digit));
memset(num ,0, sizeof(num));
int temp = n;
for(long long i = 2; i <= n; i++) {
if(temp % i== 0){
digit[c] = i;
num[c] = 0;
c++;
}
while(temp % i== 0){
num[c-1]++;
temp /= i;
}
}
}
typedef long long ll;
ll prime[N], nprime, factor[N], numfactor[N], ct;
bool isprime[N];
void makeprime() {// 打 1~N 的素数表
int i, j, temp;
nprime = 0;
memset(isprime, 1, sizeof(isprime));
isprime[1] = 0;
temp = sqrt(N + 0.0);
for(i = 2;i <= temp; ++i) {
if(isprime[i]) {
++nprime;
prime[nprime] = i;
for(j=i+i; j < N; j += i) {
isprime[j] = 0;
}
}
}
}
void makeprime2() { // 线性筛素数
memset(isprime, 1, sizeof(isprime));
int i, j;
int num = 0;
for(i = 2 ; i <= N; i++)
{
if(isprime[i])
prime[num++] = i;
for(j = 0; j < num && i * prime[j] <= N; j++)
{
isprime[i * prime[j]] = 0;
if(i % prime[j] == 0) break;
}
}
}
void divide2(ll n) {// 进行素数分解
int i;
int temp = sqrt(n + 0.0);
ct=0;
memset(numfactor, 0, sizeof(numfactor));
for(i = 1; i <= nprime; ++i) {
if(prime[i] > temp) break;
if(n % prime[i] == 0) {
factor[++ct]=prime[i];
while(n % prime[i] == 0) {
numfactor[ct]++;
n /= prime[i];
}
}
}
if(n != 1) {
factor[++ct] = n;
numfactor[ct]++;
}
}
int main() {
// 针对单一的数字
clock_t t1 = clock(),t2;
divide(N);
t2 = clock();
printf("cost time is: %d\n", t2-t1);
t1 = clock();
makeprime();
divide2(N);
t2 = clock();
printf("cost time is: %d\n", t2-t1);
t1 = clock();
makeprime2();
divide2(N);
t2 = clock();
printf("cost time is: %d\n", t2-t1);
// 复杂度也是o(n), 因为sqrt
t1 = clock();
makeprime();
t2 = clock();
printf("cost time is: %d\n", t2-t1);
// 所谓线性筛素数
t1 = clock();
makeprime2();
t2 = clock();
printf("cost time is: %d\n", t2-t1);
return 0;
}
运行结果:
于2014.11.26修正:线性筛素数应该从第一个素数开始。