C++版埃拉托斯特尼筛法2024 年 8 月 28 日 | 阅读 9 分钟 旨在识别指定范围内或 up to specified limit 'n' 的所有素数。它以古希腊数学家 Eratosthenes 的名字命名。该算法提供了一种系统的方法来筛除非素数,使其成为数论和各种计算应用中宝贵的工具。 该算法首先创建一个从 2 到 'n' 的数字列表,并最初假设它们都是素数。然后,它系统地标记每个素数的倍数,从最小的素数 2 开始。随着算法的进展,它会逐步发现给定范围内的素数。 驱动 埃拉托斯特尼筛法 的关键见解是任何素数的倍数本身都是 合数(非素数)。因此,该算法通过连续标记这些倍数来有效地过滤掉非素数候选。该过程一直持续到达到 'n' 的平方根,之后剩余的未标记数字被确认为素数。 初始化:创建一个大小为 'n+1' 的布尔数组或向量,其中每个元素代表从 0 到 'n' 的一个数字。最初,所有元素都设置为 “true”,以假定所有数字都是素数。 标记非素数:从第一个素数 2 开始。通过将 2 的所有倍数对应的数组元素设置为 “false” 来将其标记为非素数。此步骤从潜在素数列表中消除了 4, 6, 8, 10 等数字。 查找下一个未标记的数字:标记完 2 的倍数后,找到大于 2 的下一个 未标记的数字。这个数字将是下一个素数。在第一次迭代中,它是 3。 重复过程:继续通过将下一个素数(在此情况下为 3)的所有倍数标记为 非素数 来重复该过程。在下一次迭代中,找到下一个未标记的数字,它将是下一个素数(在此情况下为 5),然后重复该过程。一直重复此迭代,直到达到 'n' 的平方根。 结果:过程完成后,数组中所有 未标记的数字 都是素数。该算法已经筛除了非素数,只剩下素数。 埃拉托斯特尼筛法在查找素数方面效率很高,尤其是在处理大范围数字时,因为它避免了对每个数字单独进行昂贵的素数测试操作。相反,它系统地消除了已知素数的倍数来识别新的素数。 程序 1这是 埃拉托斯特尼筛法 算法的 C++ 代码实现,用于查找给定限制 'n' 之内的所有素数。此代码使用基本方法,带有布尔向量来标记素数和非素数。 输出 Enter the limit (n): 20 Prime numbers up to 20 are: 2, 3, 5, 7, 11, 13, 17, 19 说明
在 sieveOfEratosthenes 函数内部
在循环内
在主函数中
复杂度分析 时间复杂度 外循环:sieveOfEratosthenes 函数中的外循环从 2 迭代到 'n' 的平方根。在 Big O 符号中,这部分的时间复杂度为 O(sqrt(n))。这是因为我们只需要考虑 up to 'n' 的平方根的素数即可消除倍数。 内循环:在外循环内部,有一个内循环将当前素数 'p' 的倍数标记为非素数。内循环对每个素数 'p' 大约运行 'n/p' 次。随着我们的进展,'p' 变大,它标记的倍数数量减少。因此,所有素数的迭代总和大致为 n/2 + n/3 + n/4 + ... + n/p 该级数收敛到 n * (1/2 + 1/3 + 1/4 + ... + 1/p),在最坏情况下约等于 n * log(log(n))。 总时间复杂度:将外循环和内循环的时间复杂度结合起来,埃拉托斯特尼筛法的总体时间复杂度约为 O(sqrt(n) * log(log(n)))。 空间复杂度 埃拉托斯特尼筛法的空间复杂度由存储布尔向量 isPrime 所需的空间决定,该向量包含 'n + 1' 个元素。 因此,该算法的空间复杂度为 O(n)。 程序 2在 C++ 中实现埃拉托斯特尼筛法算法的另一种方法是使用一种更节省内存且空间需求更少的方法。此方法使用 bitset 而不是布尔向量来减少内存使用。以下是使用此方法的 C++ 实现。 输出 Enter the limit (n): 50 Prime numbers up to 50 are: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 说明
在 sieveOfEratosthenes 函数内部
在循环内
在主函数中
复杂度分析 时间复杂度 初始化阶段涉及设置一个大小为 1000001 的 bitset,代表从 0 到 'n' 的数字。此初始化步骤需要 O(n) 时间,但由于 bitset 的固定大小,在实际应用中可以视为常量。 算法的核心是外循环,负责素数检测。它迭代约 sqrt(n) 次 (O(sqrt(n))) 来识别素数。这是因为在查找素数时,无需考虑大于 'n' 平方根的数字。 内循环将素数的倍数标记为 非素数,并且总共运行约 n * log(log(n)) 次。此复杂度源于素数被发现时迭代次数的减少,在最坏情况下收敛到 n * log(log(n))。 总时间复杂度可表示为 O(n + sqrt(n) + n * log(log(n))),包括初始化、素数检测和标记倍数。实际上,内循环的贡献 n * log(log(n)) 占主导地位。这种详细的分解阐明了时间如何在各种算法步骤中分配,从而有助于对其效率进行全面理解。 空间复杂度 用于素数标记的 Bitset
附加空间 代码中还使用了一些附加变量,例如整数变量(n, p, i, first 等),它们占用固定量的内存。 因此,这些变量的空间复杂度为 O(1)。 下一个主题C++版银行家算法 |
C++ 中的 "atexit()" 函数是 C 标准库的一部分,用于注册程序退出时应调用的函数。atexit() 的主要目的是在程序退出之前提供一种执行清理任务或最终化资源的机制。...
阅读 10 分钟
如果你处理视觉效果,编写游戏需要扎实的编程技能以及对 OpenGL 和 DirectX 等几个 API 的深刻理解。对于 C++ 程序员来说,有几个游戏引擎可以简化这个过程。必需的头文件...
阅读 4 分钟
?本节将讨论 C++ 编程语言中两个或多个字符串的连接。字符串的连接意味着将两个或多个字符串组合起来,返回一个连接后的单个字符串。在连接字符串时,第二个字符串被添加到…
5 分钟阅读
C++ 允许开发人员开发强大的应用程序,它被誉为市场上最强大、最灵活的编程语言之一。在众多 C++ 函数中,`wmemmove()` 是一种处理相似数组中宽度的块移动的有用技术。这是一个深入的教程……
阅读 6 分钟
C++ 是一种强大的编程语言,可以同时处理高级抽象和低级内存管理。析构函数是导致这种情况的主要因素之一。C++ 应用程序需要析构函数来管理资源并确保正确清理。本文将介绍……
阅读 4 分钟
字符串操作是处理和处理 C 和 C++ 计算机语言中文本数据的重要组成部分。C 标准库提供了一个有用的方法 strspn(),可用于计算字符串中第一个段的长度,该段...
阅读 4 分钟
在本文中,我们将讨论 std::numeric_limits::max() 和 std::numeric_limits::min() 函数,包括它们的语法和示例。std::numeric_limits::max() 是什么? std::numeric_limits<T>:: max() 方法返回由数值类型 T 表示的最大有限数字。所有算术类型都可以用于类型 T。头文件:#include<limits> 模板:static T max() throw(); static...
阅读 2 分钟
在本文中,您将通过示例了解 C++ 中二叉树的直径。连接二叉树中任意两个节点最长路径的边数允许我们计算二叉树的直径。二叉树的直径...
5 分钟阅读
在本文中,我们将讨论 C++ 中用于计算 LCM 的内置函数及其语法和方法。在编程时,我们经常需要确定两个数之间的最小公倍数(LCM)。我们可以直接使用 C++ boost 的内置函数 boost::math::lcm()...
阅读 3 分钟
C++ 标准库提供了各种高效的容器。这些容器只是各种存储数据结构的模式版本。标准库中算法和迭代器的模板化实现等替代版本也可用。但是,容器仅用于存储项目....
阅读 4 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India