素数判定(筛选 突破常规)
来源:互联网 发布:安纳金·天行者知乎 编辑:程序博客网 时间:2024/06/06 09:36
(1)最基本素数判定方法大家熟悉,只用看看2到n(或n的平方根)之间有没有n的约数:
#include<stdio.h>
void main()
{
int i,n;
scanf("%d",&n);
for(i=2;i<n;i++)
if(n%i==0)break;
if(i<n||n==1)puts("No");
else puts("Yes");
}
此方法适用于判定较少数,数据量大时会超时。
(2)筛选法求素数也重要的求素数方法之一。这种方法主要用于打素数表,如求出n之内的所有素数,其思路是从1开始遇到一个素数就标记一下,并去掉n之内的大于它的所有倍数,直循环到n:
#include<stdio.h>
int n,i,j,a[1000001],p[100000],t=0;
void main()
{
scanf("%d",&n);
a[1]=0;
for(i=2;i<=n;i++)a[i]=1;
for(i=2;i<=n;i++)
if(a[i]){
p[t++]=i;
for(j=i+i;j<=n;j+=i)a[j]=0;
}
for(i=0;i<t;i++)
printf("%d%c",p[i],i<t-1?' ':'/n');
}
此方法也有局限性,数据量中等时才不会超时,数据量过大时也会超时,而且只能用素数打表,不能对单个数进行判定!
(3)这是我根据《离散数学》上的一个定理想到的,定理为:“若正整数a>1,且a不能被不超过a的平方根的任一素数整除,则a是素数”,实现过程如下:
#include<stdio.h>
#include<math.h>
int p[1000000],a[10000001],t=0;
int prime(int n)
{
int i,q;
q=(int)sqrt(n);
for(i=0;p[i]<=q&&t;i++)
if(n%p[i]==0)return 0;
return 1;
}
void main()
{
int n,i;
scanf("%d",&n);
for(i=2;i<=n;i++)
if(prime(i))p[t++]=i;
for(i=0;i<t;i++)
printf("%d%c",p[i],i<t-1?' ':'\n');
}
此方法可以对超大量数据的进行打表!
此方法也同样合适于素数打表,判定单个时这个方法不可取!
(4)由方法(3)延伸出另一个素数判定方法:
#include<stdio.h>
#include<math.h>
int p[8]={4,2,4,2,4,6,2,6};
int prime(int n)
{
int i=7,j,q;
if(n==1)return 0;
if(n==2||n==5||n==3)return 1;
if(n%2==0||n%3==0||n%5==0)return 0;
q=(int)sqrt(n);
for(;i<=q;){
for(j=0;j<8;j++){
if(n%i==0)return 0;
i+=p[j];
}
if(n%i==0)return 0;
}
return 1;
}
void main()
{
int n;
scanf("%d",&n);
if(prime(n))puts("Yes");
else puts("No");
}
这种方法既可以用于最快速地判定单个数,也可以用于判定超大量的数据。
此方法判定单个数时要比第(1)种方法要快得多,用于大量数据素数打表时稍逊于第(3)种方法,却要比第(2)方法快得多。
#include<stdio.h>
void main()
{
int i,n;
scanf("%d",&n);
for(i=2;i<n;i++)
if(n%i==0)break;
if(i<n||n==1)puts("No");
else puts("Yes");
}
此方法适用于判定较少数,数据量大时会超时。
(2)筛选法求素数也重要的求素数方法之一。这种方法主要用于打素数表,如求出n之内的所有素数,其思路是从1开始遇到一个素数就标记一下,并去掉n之内的大于它的所有倍数,直循环到n:
#include<stdio.h>
int n,i,j,a[1000001],p[100000],t=0;
void main()
{
scanf("%d",&n);
a[1]=0;
for(i=2;i<=n;i++)a[i]=1;
for(i=2;i<=n;i++)
if(a[i]){
p[t++]=i;
for(j=i+i;j<=n;j+=i)a[j]=0;
}
for(i=0;i<t;i++)
printf("%d%c",p[i],i<t-1?' ':'/n');
}
此方法也有局限性,数据量中等时才不会超时,数据量过大时也会超时,而且只能用素数打表,不能对单个数进行判定!
(3)这是我根据《离散数学》上的一个定理想到的,定理为:“若正整数a>1,且a不能被不超过a的平方根的任一素数整除,则a是素数”,实现过程如下:
#include<stdio.h>
#include<math.h>
int p[1000000],a[10000001],t=0;
int prime(int n)
{
int i,q;
q=(int)sqrt(n);
for(i=0;p[i]<=q&&t;i++)
if(n%p[i]==0)return 0;
return 1;
}
void main()
{
int n,i;
scanf("%d",&n);
for(i=2;i<=n;i++)
if(prime(i))p[t++]=i;
for(i=0;i<t;i++)
printf("%d%c",p[i],i<t-1?' ':'\n');
}
此方法可以对超大量数据的进行打表!
此方法也同样合适于素数打表,判定单个时这个方法不可取!
(4)由方法(3)延伸出另一个素数判定方法:
#include<stdio.h>
#include<math.h>
int p[8]={4,2,4,2,4,6,2,6};
int prime(int n)
{
int i=7,j,q;
if(n==1)return 0;
if(n==2||n==5||n==3)return 1;
if(n%2==0||n%3==0||n%5==0)return 0;
q=(int)sqrt(n);
for(;i<=q;){
for(j=0;j<8;j++){
if(n%i==0)return 0;
i+=p[j];
}
if(n%i==0)return 0;
}
return 1;
}
void main()
{
int n;
scanf("%d",&n);
if(prime(n))puts("Yes");
else puts("No");
}
这种方法既可以用于最快速地判定单个数,也可以用于判定超大量的数据。
此方法判定单个数时要比第(1)种方法要快得多,用于大量数据素数打表时稍逊于第(3)种方法,却要比第(2)方法快得多。
这几判定素数方法中第(4)种最好用,不过不容易理解,我也解释不清楚(只可意会,不可信传),大家看看哪个方法好用就用
(看到有些地方说第一种根本不能归于算法/哈哈)
1 0
- 素数判定(筛选 突破常规)
- 素数的判定(常规)
- 100以内素数判定(筛选法)
- POJ2262 素数判定,万能的素数筛选
- 素数判定(2012)
- 素数筛选(模板)
- hdu1164(素数筛选)
- 素数筛选(转载)
- 线性筛选素数(欧拉筛选)
- hdoj2012素数判定(素数打表)
- 素数判定 (素数)【HDU】-2012
- 素数判定(费马小定理)
- 梅森素数(判定)
- 质数(素数)判定算法
- 素数筛(筛选法求素数)
- 素数筛选法(素数筛)
- 1716: Divisors(素数筛选)
- pku2689(筛选素数法)
- POJ-2609-双塔dp
- 像"机器"一样思考
- 导入兼容包
- 向量空间模型(VSM)在文档相似度计算上的简单介绍
- A+B Problem II
- 素数判定(筛选 突破常规)
- webStorm设置颜色和字体大小
- 机器学习并没有那么深奥,它很有趣(2)
- SpringMvc对Servlet原生API的支持
- 矩阵路径最大和
- 汪国新委员参与2016两会文艺组讨论
- Android--权限列表
- 中国日报、大众网等媒体报道 汪国新委员中国式接送有待解决
- 机器学习并没有那么深奥,它很有趣(3)