质数及其判法

目录

目录地址

什么是质数

数学家们希望用乘法表示所有的正整数

这时候,他们发现,有一些数字(假定为 \(p\) ),它们只能用 \(1\times p\) 的形式表示(不考虑负因数),其它不能写成任何别的形式

对于这种数字,他们称呼为 质数 ,或称呼为 素数

而换句话说,它们只能分解为 \(1\) 乘上它本身;也就是说,它的因数只有 \(1\) 与它本身

这就是质数最重要的性质,也是它的定义

而对于其它的数字,我们称呼为 合数

合数的一些性质我们将会在后面的贴子中提到


质数的判法

对于一个数字 \(n\) 我们如何判定它是不是质数呢?

根据定义,我们很容易想到:枚举数字,查询是否只有 \(1\) 与 \(n\) 是它的因数

而如果数字 \(m\) 是数字 \(n\) 的因数,很显然,存在数字 \(k\) 使得 \(k\times m=n\)

反过来,我们可以写作 \(n\div m=k\cdots0\)

也就是说,如果 \(m\) 是数字 \(n\) 的因数, \(n\) 除以 \(m\) 的因数一定为 \(0\)

既然质数的因数只有 \(1\) 与它本身,那么其他数字除完的因数就一定不能为 \(0\)

根据数字的因数一定小于等于它本身,我们很快就可以写出程序(以 C++ 为例)

bool isprime=1;
for(int i=1;i<=n;i++){
    if(n%i==0&&i!=1&&i!=n){
        isprime=0;
    }
}

当然,其实我们这样做的话,直接遍历的范围改成 \(2\)~\((n-1)\) 就行了

bool isprime=1;
for(int i=2;i<=n-1;i++){
    if(n%i==0){
        isprime=0;
    }
}

这样一来,时间复杂度是 \(O(n)\)


优化

时间复杂度能更快吗?

可以的

我们现在的思路是:枚举数字,查看 \(n\) 是否是合数

但我们想想,如果 \(n\) 是合数,那么它一定能写成 \(n=m\times k(m,k\neq 1,n)\) 的形式

我们直接假定 \(m\leq k\)

那么,显然 \(m\leq \sqrt{n}\)

这一步的证明我们可以用反证法:

若 \(m>\sqrt{n}\) , 则 \(k\times m\geq m\times m=m^2>(\sqrt{n})^2=n\) 就不是 \(n\) 了

所以 \(m\leq sqrt{n}\)

我们可以利用这个来优化我们的代码:我们修改上界,搜到 \(\sqrt n\) 即可

bool isprime=1;
for(int i=2;i<=sqrt(n);i++){
    if(n%i==0){
        isprime=0;
    }
}

当然,能不用 sqrt 函数我们尽量就不要用,毕竟它还需要支持实数的运算,跑得并不快

我们用 i*i<=n 来代替 i<=sqrt(n) 可以降低常数

bool isprime=1;
for(int i=2;i*i<=n;i++){
    if(n%i==0){
        isprime=0;
    }
}

复杂度 \(O(\sqrt n)\)

当然,想优化常数还能再优化:判定完不是质数就可以直接退出了

bool isprime=1;
for(int i=2;i*i<=n;i++){
    if(n%i==0){
        isprime=0;
        break;
    }
}

或者我们搞成内联函数的形式:

inline bool isprime(int n){
    for(int i=2;i*i<=n;i++) if(n%i==0) return 0;
    return 1;
}

这样就完成了

原文地址:https://www.cnblogs.com/JustinRochester/p/12330611.html

时间: 2024-08-30 12:31:02

质数及其判法的相关文章

质数——6N&#177;1法

6N±1法求素数 任何一个自然数,总可以表示成为如下的形式之一: 6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,-) 显然,当N≥1时,6N,6N+2,6N+3,6N+4都不是素数,只有形如6N+1和6N+5的自然数有可能是素数.所以,除了2和3之外,所有的素数都可以表示成6N±1的形式(N为自然数). 根据上述分析,我们只对形如6 N±1的自然数进行筛选,这样就可以大大减少筛选的次数,从而进一步提高程序的运行效率和速度. 以下代码需要自然数大于10 . public

质数的性质

[质数的性质] 1.不等于1的自然数,如果只有2个约数,就叫做质数:如果有2个以上的约数,就叫做合数. 2.任何不是1的自然数,至少存在一个是质数约数. 3.如果a.b是质数,则形如an+b的数中,包含着无限个质数. 4.一切大于2的质数,不是形如4n+1,就是形如4n-1. 5.(4n+1)*(4n+1),结果还是4n+1. 6.质数的判定法. 例题 7.一切不大于sqrt(N)的质数中没有一个是N的约数,那么N一定是个质数. 8.100以内的素数表. 9.质数表的构造定理. 10.任一个合数

Java打印素数(质数)

要求:打印 2 - 100000 当中的素数与非素数.(素数定义:在大于1的自然数中,除了1和它本身以外不再有其他因数) 1. 常规方式--对正整数n,如果用2到  之间的所有整数去除,均无法整除,则n为质数: // sqrt 法 public static void printPrime1(int num) { boolean[] isPrimes = new boolean[num + 1]; for (int i = 2; i < isPrimes.length; i++) { isPri

prime distance ( 大区间内部质数

# 题意 给定两个整数l,r,求在[l,r]区间内距离最近的一对相邻质数,和距离最远的一对相邻质数 l,r ∈ [1 , 231-1] 其中r-l <= 1e6 # 题解 l,r的范围很大,大约是2e9 线性算法也无法求出[1,r]的所有质数,但是r-l的范围小, 任何一个合数必定会包含一个不超过 √n 的质因数,所以求出 2~√r 的所有质数, 对于每个质数,将[l,r]中能整除这个数字的标记,剩下的就是区间内的质数. 对于质数两两比较求最值即可 复杂度 O (√r * log (log r)

哈希容器

目录 hashtable 开链法 hashtable的桶子(buckets)与节点(nodes) haah table的图示 hashtable实现 hashtable的节点实现 hashtable的迭代器实现 hashfunction的设计 unordered_set hashtable 将一系列数放入容器中,将数除以内存的大小M,得到的余数挂在每个篮子下面.篮子的个数M一般取质数,当篮子所挂的链表长度大于篮子个数M时,就要rehashing,扩充篮子的数量(vector二倍扩充,不过扩充以后

藏通别圆

众生根性皆不一,如来巧说各不同. 天台智者一怒震,五时八教尽包融. 天台宗判一代时教为五时八教.五时是:华严时.阿含时.方等时.般若时.法华涅槃时:八教是:藏.通.别.圆,顿.渐.秘密.不定.五时是从竖的方面说,把一代时教,分为五个时期:八教是从横的方面说,把一代时教,分成八种教义.而八教中,顿.渐.秘密.不定四教,是说教时所用的仪式,称做化仪四教:藏.通.别.圆四教,是教法中所含有的义理,称做化法四教.…… 或者以为讲演经论,只要根据正文,依文解义,便可明白,何必判教?这是不懂佛法的说法.且举

POJ 1228 Grandpa&#39;s Estate --深入理解凸包

题意: 判断凸包是否稳定. 解法: 稳定凸包每条边上至少有三个点. 这题就在于求凸包的细节了,求凸包有两种算法: 1.基于水平序的Andrew算法 2.基于极角序的Graham算法 两种算法都有一个类似下面的语句: for(int i=0;i<n;i++) { while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--; ch[m++] = p[i]; } 这样的话,求出来就是最简凸包,即点数尽量少的凸包,因

进程分配

筛质数进阶 之前筛质数程序创建了201个子进程,由于进程号有限,所以可以采用以下三种方法 1.分块法:将201个子进程分成N等份.eg:N=3,那么201个子进程平均分成3份 2.交叉分配法:将201个子进程依次分配给N个进程 3.进程池:用一个进程取质数,并将其丢给下边的线程或者进程处理质数 ===================================================================== 交叉分配法: #include <stdio.h> #incl

凸包——Graham扫描法和Andrew算法

凸包:能围住所有给出的点的面积最小的多边形(个人理解) Graham:选取y值最小的点,将其它点极角排序,依次把1~n号点加入栈中,判断当前点.栈顶.栈顶下面那个点三者的关系(嘻嘻),一直这样做就好了 判断用叉积,也就是如下图的要判掉(top--) 其实上图是不对的哦,你有没有反应过来呢~按极角排序后不会有这种情况哦,肯定是先连a[i],再连s[top]的 具体实现看代码吧~ #include<cstdio> #include<cmath> #include<algorith