/*
* 程序的版权和版本声明部分:
* Copyright (c) 2014,郑州大学SIAS国际学院
* 作 者: 王 杰
* 完成日期:2014 年 1 月 18 日
*
* 对任务及求解方法的描述部分:
* 输入描述: 略或见注释、总结
* 问题描述: 略或见注释、总结
* 程序输出: 略或见注释、总结
* 问题分析: 略或见注释、总结
* 算法设计: 略或见注释、总结
*/
/*
思路:打表,并且尽可能的少判断数。
1、先进行筛选,把非常明显的数筛掉(剩下的还有合数)
2、然后进一步筛选,prime判断,不是即跳过,是就送进biao[]内(要注意的是打表结束后,biao[]还有很多元素为0)
3、while循环求n(用continue保证不退出,也可以把打表定义成函数),然后循环输出n之前的素数
*/
#include<stdio.h>
//#include<time.h>
#define size 100000
int biao[size]={2,3,5}; //把数组开到函数外,并赋初值(也可以memset(),不过觉得这种方式比较好)
//素数判定函数
/*
int prime(int n)
{
register int i;
if(n<2) return 0; //n为1时考虑到了
for(i=2;i*i<=n;i++)
if(n%i==0) return 0;
return 1;
}
*/
//素数判定函数
int prime(int n)
{
if((n!=2 && !(n%2)) || (n!=3 && !(n%3)) || (n!=5 && !(n%5)) || (n!=7 && !(n%7)))
//先把能被2,3,5,7整除的数去除,减少运算量,从而提高运算效率
return 0;
int i;
for(i=0;biao[i]*biao[i]<=n;i++)
if(!(n%biao[i])){
return 0;
}
return 1;
}
//也可以把打表定义成函数
/*
int dabiao(void)
{
int i,k;
int gab=2;
for(i=7;i<=size;i=i+gab){
if(prime(i)){
biao[k=3]=i;
k++;
gab=6-gab;
}
else
gab=6-gab;
}
}
*/
int main()
{
int n;
register int j;
register int i,k=3;
//在筛选的同时打表
int gab=2;
for(i=7;i<=size;i+=gab){
if(prime(i)){
biao[k++]=i;
gab=6-gab; //4、2、4、2、4、2
}
else
gab=6-gab;
}
//输入n,输出素数
scanf("%d",&n);
while(n){
for(j=0;biao[j]<=n && biao[j]!=0;j++){
printf("%d ",biao[j]);
}
printf("\n");
//printf("TIME=%.2lf\n",(double)clock());
scanf("%d",&n);
}
return 0;
}
上面的代码超时
优化后的:埃筛法(目前最好的一种查找素数方法)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int arr[2000001]={0};
int main()
{
int n,i,j;
for(i=2;i<=2000000;i++) //打表,数组下标代表要判断的数,0代表是素数,1代表不是
{
if(arr[i]==0)
for(j=i+i;j<=2000000;j+=i) //筛法判断素数
arr[j]=1;
}
while(scanf("%d",&n) && n)
{
printf("2");
for(i=3;i<=n;i++)
if(arr[i]==0)
printf(" %d",i);
printf("\n");
}
}
两种方法的分析比较:
上面的那种:i 是在4 2 4 2 4 2 4 2 ........的跳,而且每跳一次就要判断一下是否为素数,就又是素数判定循环
下面的那种:前期看起来有点慢,但随着找到的素数越来越多,到后面很多就是if判断,不用再筛选(fou循环)(如2, 一百万 有一半奇数,一半偶数,第一次 i=2 时就已经筛掉了一半的数,到后面的3 5 7.......就会越来越快,因为只是if判断,不会fou循环);而且确定的素数越来越大,跳的间隔就会越来越大,越到后面筛选的越快
(通俗解释:当 i=2 时,筛掉一半,剩下一半;当 i=3 时,再在剩下的一半的基础上筛掉这一半的1/3,已经筛掉的只需 if 判断就行了;一直 i++;到后期会越来越快)
(对于没有筛掉的:筛 ,并且越到后筛的越快 , 对于已经筛掉的:if 判断即可)