IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C++高效的质数的判断(2种方法) -> 正文阅读

[数据结构与算法]C++高效的质数的判断(2种方法)

前提准备

在开始质数的讨论之前,我们先预备一下:

质数的定义:若一个正整数除了1和它自身之外不能被任何自然数整除,则该数称为质数,也叫素数。否则为合数

由定义可知,所有小于等于1的数既不是质数,也不是合数

质数的分布较为稀疏,对于一个足够大的数S,不超过S的质数大约有\frac{N}{InN}个,也就是说每InN个数约有一个质数,这点读者了解即可。

质数的判断(试除法)

对于质数的判断,最简单也最容易想到的方法就是一个一个的筛选,也叫试除法。

如果要判断一个数N,那么我们要对2~N-1的所有数都筛选一遍吗,显然不用。首先肯定的是N-1肯定不能整除N,那么是否能进一步缩小范围。我先给出答案:2~sqrt(N)

严谨的证明过程如下图:(注释:\left \lfloor \right \rfloor\left \lceil \right \rceil分别表示向下,向上取整)

?那好,利用这个性质,我们就可以写出一下代码:

Code(O(sqrt(N)))

#include<cstdio>
bool isprime(int num){
	if(num==2)
	    return true;
	if(num%2==0 || num<2)
	    return false;
	else{
		for(int i=3;i*i<=num;i+=2){
			if(num%i==0){
				return false;
			}
		}
		return true;
	}
}
int main(){
	int x;
	scanf("%d",&x);
	if(isprime(x)){
		printf("Yes");
	}
	else{
	    printf("No");
	}
	return 0;
} 

尽管如此,这个代码还是优化了许多,我们单独考虑2这个情况,然后从3开始只枚举奇数。

难道这就是最快的算法吗?


Miller-Robbin算法

其实还有一个更厉害的算法,名为Miller-Robbin算法,要想学会,我们首先需要理解一个定理:

费马小定理:

? ? ? ? ? ? ? ? ? ? ? ? ?对于一个质数 p,任意一个自然数a,那么:?a^{p}\equiv a(mod p) ——1

证明如下图所示:

?证明完之后,我们可以左右同时除以一个a,变形成:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?a^{p-1}\equiv 1(mod p)——2

这个就不一定成立了,可以发现,当a是p-1的倍数时,左式一定是p的倍数,mod一个p就等于0了,不可能等于右边,所以我们必须加上一个条件

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? a与p-1互质

好了,这就是费马小定理。值得注意的是,费马小定理是判断素数的必要不充分条件。如果一个数是质数,它必然满足一上的等式。但是,满足上列等式的数,并不一定是质数。如:

561
1105 
1729 
2465
2821
6601 
8911 
10585
15841
29341
41041 
46657
52633
62745
63973 
75361
101101
115921 
126217 
162401
172081
188461
252601
278545
294409
314821
334153
340561
399001
410041
449065
488881
512461

?这种合数称之为卡迈克尔数,561是最小的。他们并不满足费马小定理的逆定理!!!可迈克尔数http://oeis.org/A002997

但是,这种事情发生的概率还是比较小的,我们可以随机生成一批数,排除掉能被p-1整除的数,如果它满足费曼小定理的逆定理,那么该数很大程度上可以称之为质数,不确定就多判定几次。我们再配合一个快速幂求出 a^p-1 mod p的值,完美。

快速幂的详解https://blog.csdn.net/way_back/article/details/122760048?spm=1001.2014.3001.5501

Code(O(1))

#include<cstdio>
#include<cstdlib>
int x;
int pow(int a){
	int b=x-1;
	int ans=1;
	while(b>0){
		if(b & 1){
			ans=((ans%x)*(a%x))%x;
		}
		a=a*a%x;
		b>>=1;
	}
	return ans;
}
bool isprime(){
	int loop=10;
	while(loop--){
		int t=rand();
		while(t%x==0){
			t=rand();
		}
		if(pow(t)!=1){
		    return false;
		}
	}
	return true;
}
int main(){
	scanf("%d",&x);
	if(isprime()){
		printf("Yes");
	}
	else{
		printf("No");
	}
	return 0;
}

用10个循环去判断那些卡迈克尔数,结果如下:

?没有问题,但我要循环5次的话,就出现问题了,如图所示:

?有几个数就判断错误了。我们在保证正确率的前提下再提高效率。


下一个内容我们要讨论如何在一个区间内把质数都筛选出来,不见不散

C++区间质数的筛选https://blog.csdn.net/way_back/article/details/122787801

End~~~

写作不易,谢谢大家支持

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 21:57:54  更:2022-02-05 22:00:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 18:54:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码