对于质数的研究
1.常对象2.类为什么要传引用3.为什么要用const修饰某个对象?4.nth_element算法5.sprintf函数和sscanf函数6.scanf为什么比cin要快?7.矩阵旋转8.C++中的位运算9.std::ios::sync_with_stdio(0) 加速10.约数和倍数的性质
11.对于质数的研究
12.最大公约数和最小公倍数13.sort函数中的第三个参数:自定义排序方式14.排序15.大根堆和小根堆的介绍16.next_permutation17.线性dp:大盗阿福(打家劫舍)18.线性dp:最长上升子序列19.线性dp:最长公共子序列20.线性dp:最长公共子串21.宏定义define的用法22.算法比赛中常用的快读试除法判断质数
试除法的思想
试除法是一种简单且直观的方法,用来判断一个数是否为质数。它的基本思想是:对于待判断的数 ( n ),从小到大地试除每个小于 ( n ) 的数 ( i ),如果 ( n ) 能被任何 ( i ) 整除且 () 和 (),则 ( n ) 不是质数;否则,( n ) 是质数。
下面是用试除法判断一个数 ( n ) 是否为质数的示例代码:
#include <iostream> using namespace std; bool isPrime(int n) { if (n <= 1) return false; // 小于等于1的数不是质数 if (n == 2) return true; // 2是质数 // 从2开始试除,一直试除到 sqrt(n) for (int i = 2; i * i <= n; i++) { if (n % i == 0) { return false; // 如果能整除,则不是质数 } } return true; // 如果没有能整除的数,则是质数 } int main() { int n; cout << "Enter a number: "; cin >> n; if (isPrime(n)) { cout << n << " is a prime number." << endl; } else { cout << n << " is not a prime number." << endl; } return 0; }
解释:
-
函数
isPrime
:- 首先判断如果 ( n \leq 1 ),则返回
false
,因为质数定义是大于1的正整数。 - 如果 ( n = 2 ),则返回
true
,因为2是质数。 - 接下来,用一个循环从2开始到 ( \sqrt{n} )(因为如果 ( n ) 有大于 ( \sqrt{n} ) 的因子,它的对称因子必然小于 ( \sqrt{n} ))逐个试除。
- 如果能整除任何一个数 ( i ),则返回
false
,表示 ( n ) 不是质数。 - 如果循环结束都没有找到能整除的数,则返回
true
,表示 ( n ) 是质数。
- 首先判断如果 ( n \leq 1 ),则返回
-
主函数
main
:- 从用户输入一个数 ( n ),然后调用
isPrime
函数判断它是否为质数,并输出相应的结果。
- 从用户输入一个数 ( n ),然后调用
总结:
试除法是一种简单但有效的方法来判断一个数是否为质数。它的时间复杂度为 ( O(\sqrt{n}) ),效率较高,尤其适合用于判断单个数是否为质数的场景。
2.埃氏筛法求质数
埃氏筛(Sieve of Eratosthenes)是一种用来找出一定范围内所有素数的经典算法。它由古希腊数学家埃拉托斯特尼斯(Eratosthenes)发明,用于解决寻找素数的问题。
算法原理
埃氏筛的基本思想是:
- 初始化一个布尔类型的数组,称为标记数组(或筛选数组),用来标记每个整数是否为素数。数组的下标表示整数,数组的值为
true
表示该下标对应的整数是素数,为false
表示不是素数。 - 从小到大依次遍历每个整数
i
,若发现i
是素数,则将i
的所有倍数标记为非素数(即将对应位置的布尔值设为false
),除了i
本身。
具体步骤如下:
- 初始化一个布尔数组
is_prime
,将数组中所有元素初始化为true
。 - 将
is_prime[0]
和is_prime[1]
设为false
,因为 0 和 1 不是素数。 - 从
2
开始遍历到sqrt(n)
,对于每个素数i
,将i
的所有倍数(除了i
本身)设为false
。 - 最终,所有值为
true
的下标即为素数。
算法优化
- 减少遍历范围: 在埃氏筛中,我们只需要遍历到
sqrt(n)
就可以了,因为如果i
是n
的因子,那么n/i
也一定是n
的因子。 - 空间优化: 如果要找出的素数范围不是很大,可以优化空间。例如,使用标记数组只标记奇数,可以将空间使用减半。
示例
以找出小于等于 n
的所有素数为例,以下是使用埃氏筛的 C++ 实现示例:
#include <iostream> #include <vector> std::vector<int> sieve_of_eratosthenes(int n) { std::vector<bool> is_prime(n + 1, true); // 默认所有数都是素数 std::vector<int> primes; is_prime[0] = is_prime[1] = false; // 0和1不是素数 for (int i = 2; i * i <= n; ++i) { if (is_prime[i]) { for (int j = i * i; j <= n; j += i) { is_prime[j] = false; // 将i的倍数标记为非素数 } } } for (int i = 2; i <= n; ++i) { if (is_prime[i]) { primes.push_back(i); // 收集所有素数 } } return primes; } int main() { int n = 30; // 找出小于等于30的所有素数 std::vector<int> primes = sieve_of_eratosthenes(n); std::cout << "Prime numbers less than or equal to " << n << " are:\n"; for (int prime : primes) { std::cout << prime << " "; } std::cout << std::endl; return 0; }
在这个示例中,sieve_of_eratosthenes
函数返回小于等于 n
的所有素数的列表。程序首先初始化一个标记数组 is_prime
,然后根据埃氏筛的算法进行标记,最后收集所有值为 true
的下标作为素数输出。
埃氏筛是一种高效的算法,时间复杂度为 O(n log log n),适用于寻找较小范围内的素数集合。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效