当前位置:首页 > 教育 >

判断质数最快的算法(最简单的判断质数的方法)

来源:原点资讯(www.yd166.com)时间:2024-06-29 21:47:30作者:YD166手机阅读>>

质数筛法是用于找出一定范围内所有质数的算法。质数也叫素数,是指只有1和它本身两个约数的自然数,0和1既不是质数也不是合数。首先根据质数的定义,可以提炼出以下几点内容

  1. 素数是自然数,因此是整数
  2. 素数是大于1的自然数,因此小于等于1的数字都不是素数(包括负数,0和小数)
  3. 素数只有两个因数,1和自身

结合1,2,3点,可以推断出,在自然数范围内,最小的素数是2。



筛质数的方法主要有三种:朴素筛法、埃氏筛法(埃拉托色尼筛法)和欧拉筛法。以下是这三种方法的详细归纳总结:

朴素筛法 朴素筛法直接根据质数的定义来判断一个数是否为质数。它从2开始遍历到n,对于每个数i,检查是否有比i小的数能够整除i。如果没有,那么i就是质数。朴素筛法的时间复杂度较高,为O(n^2)。

代码模板如下:

// 定义一个函数来判断一个整数n是否为质数 bool isPrime(int n) { // 如果n小于2,直接返回0,因为0和1都不是质数 if (n < 2) return 0; // 初始化一个变量tmp,用于存储n-1,因为只需要检查到n-1的因子 int tmp = n - 1; // 从2开始遍历到tmp(即n-1),检查是否有数能整除n for (int i = 2; i <= tmp; i ) { // 如果n能被i整除,说明n不是质数,返回0 if (n % i == 0) { return 0; } } // 如果循环结束后没有找到能整除n的数,说明n是质数,返回1 return 1; } // 主函数,用于遍历从2到n的所有整数,并打印出所有质数 int main() { // 假设n是我们要筛选的数的范围上限 int n; // 这里需要定义n的值,例如:n = 100; // 遍历从2到n的所有整数 for (int i = 2; i <= n; i ) { // 使用isPrime函数判断当前的i是否为质数 if (isPrime(i) == 1) { // 如果是质数,打印出来 printf("%d ", i); } } return 0; // 主函数返回0表示程序正常结束 }

同时可在此基础上更进一步:一个数去除以比它的一半还要大的数,一定除不尽的,所以只需要除到n/2即可。

// 初始化一个变量tmp,用于存储n/2,因为只需要检查到n/2的因子 int tmp = n / 2;

再进一步:一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中也不需要遍历到n/2,遍历到sqrt(n)即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数。因此只要从2枚举到 √n即可。

// 初始化一个变量tmp,用于存储 √n,因为只需要检查到 √n的因子 int tmp = sqrt(n);

⭐值得注意的是,此时的时间复杂度是O(n^(3/2))



埃氏筛法(埃拉托色尼筛法) 埃氏筛法是一种更高效的筛法,它基于一个原理:一个合数总是可以分解成若干个质数的乘积。算法步骤如下:

  1. 初始化一个布尔数组,表示每个数是否为质数(true表示质数,false表示非质数)。
  2. 从2开始,将当前最小的质数的倍数标记为非质数。
  3. 重复步骤2,直到遍历到n。

埃氏筛法的时间复杂度为O(n log log n),因为它避免了对每个数进行多次筛选。

代码模板如下:

// 定义一个常量maxn,表示筛法的最大范围 const int maxn = 1e7; // 创建一个布尔数组IsPrime,用于标记每个数是否为质数(true表示质数,false表示非质数) bool IsPrime[maxn]; // 创建一个整数数组prime,用于存储筛选出的质数 int prime[maxn]; // 定义一个函数Era_prime,用于执行埃氏筛法并返回质数的个数 int Era_prime(int n) { // 初始化计数器tot,用于记录找到的质数个数 int tot = 0; // 使用memset函数初始化IsPrime数组,将所有数标记为质数(true) memset(IsPrime, true, sizeof(IsPrime)); // 将0和1标记为非质数(false) IsPrime[0] = false; IsPrime[1] = false; // 从2开始遍历到n,执行筛法 for (int i = 2; i <= n; i ) { // 如果当前数i被标记为质数(IsPrime[i]为true) if (IsPrime[i]) { // 将当前质数i添加到prime数组中,并更新质数计数器tot prime[tot ] = i; // 从i的2倍开始遍历,将i的所有倍数标记为非质数(false) for (int j = i * 2; j <= n; j = i) { IsPrime[j] = false; } } } // 返回找到的质数总数 return tot; }

这段代码实现了埃氏筛法,它是一种高效的质数筛选算法。通过遍历从2到n的所有整数,并标记所有已知质数的倍数为非质数,从而筛选出所有质数。这种方法的时间复杂度为O(n log log n),比朴素筛法的O(n^2)要高效得多。在实际应用中,这个函数可以用来找出1到n之间所有的质数。



欧拉筛法

欧拉筛法是埃氏筛法的优化版本,它只对每个数进行一次筛选。算法的核心思想是,每个合数只会被它的最小质因数筛去。

与此想法相同,有一个定理叫算术基本定理(唯一分解定理):任何合数都能表示为若干质数的乘积,且该分解因式是唯一的。(不考虑顺序性)

原理:规定每个合数只会被它最小的质因数筛去。(后面的质因数直接跳过),这个最小的质因式必定小于它本身。

算法步骤如下:

  1. 初始化一个布尔数组,表示每个数是否为质数。
  2. 从2开始,对于每个质数i,将其倍数标记为非质数,但只到i的平方根。
  3. 如果在标记过程中发现i能被某个质数整除,那么跳过这个质数,因为i已经被之前的质数筛去了。

欧拉筛法的时间复杂度为O(n),因为它在每个数上只进行一次操作,大大减少了计算量。

代码模板如下:

// 定义一个常量maxn,表示筛法的最大范围 const int maxn = 1e7; // 创建一个布尔数组IsPrime,用于标记每个数是否为质数(true表示质数,false表示非质数) bool IsPrime[maxn]; // 创建一个整数数组prime,用于存储筛选出的质数 int prime[maxn]; // 定义一个函数Euler_prime,用于执行欧拉筛法并返回质数的个数 int Euler_prime(int n) { // 初始化计数器tot,用于记录找到的质数个数 int tot = 0; // 使用memset函数初始化IsPrime数组,将所有数标记为质数(true),0和1标记为非质数(false) memset(IsPrime, true, sizeof(IsPrime)); IsPrime[0] = false; IsPrime[1] = false; // 从2开始遍历到n,执行欧拉筛法 for (int i = 2; i <= n; i ) { // 如果当前数i被标记为质数(IsPrime[i]为true) if (IsPrime[i]) { // 将当前质数i添加到prime数组中,并更新质数计数器tot prime[tot ] = i; // 遍历已经找到的质数列表 for (int j = 0; j < tot; j ) { // 如果i乘以当前质数列表中的质数prime[j]的结果大于n,跳出内层循环 if (i * prime[j] > n) { break; } // 将i的倍数标记为非质数(false) IsPrime[i * prime[j]] = false; // 如果i能被prime[j]整除,说明i已经被筛过了,跳出内层循环 if (i % prime[j] == 0) { break; } // 由于prime数组中的质数是从小到大排列的,所以i乘以其他更大的质数的结果 // 一定会被prime[j]的倍数筛掉,因此可以直接跳出内层循环 } } } // 返回找到的质数总数 return tot; }

这段代码实现了欧拉筛法,它是埃氏筛法的一个优化版本。欧拉筛法的核心思想是,对于每个合数,只筛选出它的最小质因数,这样可以避免重复筛选。这种方法的时间复杂度为O(n),因为它在每个数上只进行一次操作,大大减少了计算量。在实际应用中,这个函数可以用来找出1到n之间的所有质数。

,

栏目热文

做案子什么意思(上案子是啥意思)

做案子什么意思(上案子是啥意思)

如何开庭  到法院打官司的人,大部分都要经过庭审这一关。庭审即开庭审理,就是打官司的双方在法官的主持下,在法庭之上,直接...

2024-06-29 21:11:03查看全文 >>

做执事是什么意思(善作执事是什么意思)

做执事是什么意思(善作执事是什么意思)

在农村,谁家的红白喜事都是全村人的事情。像我们这里,都是一家有事全村前来帮忙。而办事情的时候,往往都会有一个人出来统筹主...

2024-06-29 21:53:21查看全文 >>

自己开微店怎么做(怎么查看自己开微店了没有)

自己开微店怎么做(怎么查看自己开微店了没有)

现在像淘宝、拼多多都是中心流量的,开了店铺,是否有流量取决于你的花钱营销。而自己的小店呢,是没有中心流量的,此时就是需要...

2024-06-29 21:11:37查看全文 >>

端午节红绳怎么自己做(端午节五彩绳如何最简单制作)

端午节红绳怎么自己做(端午节五彩绳如何最简单制作)

汉·应劭《风俗通》中有云:“五月五日,以五色线系臂,名长命缕”。中国古代崇拜五色,以五色为吉祥色。人们认为,将五彩线系在...

2024-06-29 21:37:14查看全文 >>

平行志愿顺序有影响么(平行志愿填写顺序有影响吗)

平行志愿顺序有影响么(平行志愿填写顺序有影响吗)

3月30日上午,青岛市政府新闻办举行了“普通高中和职业高中招生政策解读”媒体通气会。会上,青岛市招生考试院中招处处长朱海...

2024-06-29 21:43:15查看全文 >>

虾米制作方法(家庭自制虾米的做法)

虾米制作方法(家庭自制虾米的做法)

大家好,这里是【刘一手美食】,关注老刘,每天分享一道好吃又实用的家常菜1、虾皮是毛虾的干制品,有生干品和熟干品两种。虾...

2024-06-29 21:39:16查看全文 >>

适合女人一个人做的特色小吃店(适合一个女人做的小吃简单又挣钱)

适合女人一个人做的特色小吃店(适合一个女人做的小吃简单又挣钱)

以下是一些适合女人一个人经营的生意:1. 线上店铺:可以开设自己的线上店铺,销售自己喜欢的产品,如手工艺品、自制食品、时...

2024-06-29 21:18:42查看全文 >>

适合一个女人晚上做的小吃(适合女人一个人干的小吃)

适合一个女人晚上做的小吃(适合女人一个人干的小吃)

来源:利姐美食声明:此文版权归原作者所有,若有来源错误或者侵犯您的合法权益,您可联系我们,我们将及时进行处理。我想告诉全...

2024-06-29 21:28:56查看全文 >>

地摊上最吸引女人的是啥东西(地摊什么东西最受女孩子欢迎)

地摊上最吸引女人的是啥东西(地摊什么东西最受女孩子欢迎)

90后美少女下班摆摊卖穿戴甲,给女儿攒奶粉钱。欢迎收看90后打工人下班摆摊卖穿戴甲苟活的一天。因为蓝帽叔叔说不要让我们摆...

2024-06-29 21:35:31查看全文 >>

适合一人开店的小吃(适合一个人晚上开店做的小吃)

适合一人开店的小吃(适合一个人晚上开店做的小吃)

真正赚钱的小吃生意到底有多赚呢?小编以一个侧面例子做下说明:惠福莱的一位老顾客曾经透露过,他所在的美食街,自家不到5米厂...

2024-06-29 21:46:13查看全文 >>

文档排行