最近几天脑子越来越来笨了,一个简单的素数环问题纠结一天,没这么搞懂回溯的思路,不过涉及素数的话,突然想总结一下常用的素数打表,

一般用的是下面的代码:

#include <math.h>//素数打表
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define maxn 1000000
bool p1[maxn]; //判断p[i]中的i是否为素数
int p2[maxn]; //存储素数
void prim_num()
{
int i,j,n;
for(i=1; i<=maxn; i++)
p1[i]=true;
n=(int)sqrt(maxn);
for(i=2; i<=n; i++)
{
for(j=i+i; j<=maxn; j+=i) //素数的合肯定不是素数,这就是判断哪些数不是素数
{
p1[j]=false;
}
}
j=1;
for(i=1; i<=maxn; i++) //把素数存储入pmaxn[N],下表从1开始
{
if(p1[i])
{
p2[j++]=i;
}
}
}
int main()
{
int i;
prim_num();
for(i=1;i<=100;i++) //输出前100个的素数
{
printf("%d ",p2[i]);
}
return 0;
}

从网上找到了另一种写法,效率明显提高不少,线性筛法,目前还在深究。。。。。

代码如下:

/*
遇到素数需要打表时,先估算素数的个数:
num = n / lnx;
num为大概数字,越大误差越小(只是估计,用于估算素数表数组大小)
线性筛法wwwww
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 10010000
int n;
bool visit[maxn];
int prime[maxn];
void isprime()
{
memset(visit, true, sizeof(visit));
int num = 0;
for (int i = 2; i <= n; ++i)
{
if (visit[i] == true)
{
num++;
prime[num] = i;
}
for (int j = 1; ((j <= num) && (i * prime[j] <= n)); ++j)
{
visit[i * prime[j]] = false;
if (i % prime[j] == 0) break; //深究之处!
}
}
}
int main()
{
memset(prime, 0, sizeof(prime));
int count= 0;
scanf("%d",&n);
isprime();
for(int i = 0; i <= n; ++i)
if(prime[i])
{
printf("%d ",prime[i]);
count++;
}
printf("\n");
printf("the sum of prime num is:%d\n",count);
return 0;
}

以后要用到素数的话, 直接复制,方便不少