”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 开发高效算法 - 使用大 O 表示法测量算法效率

开发高效算法 - 使用大 O 表示法测量算法效率

发布于2024-07-31
浏览:823

算法设计是开发解决问题的数学过程。算法分析是预测算法的性能。前面两章介绍了经典的数据结构(列表、堆栈、队列、优先级队列、集合和映射)并应用它们来解决问题。本章将使用各种示例来介绍用于开发高效算法的常用算法技术(动态规划、分而治之和回溯)。

Big O表示法获得了一个根据输入大小衡量算法时间复杂度的函数。您可以忽略函数中的乘法常数和非支配项。假设两种算法执行相同的任务,例如搜索(线性搜索与二分搜索)。哪一个更好?要回答这个问题,您可以实现这些算法并运行程序以获得执行时间。但这种方法有两个问题:

  • 首先,许多任务在计算机上同时运行。特定程序的执行时间取决于系统负载。
  • 其次,执行时间取决于具体的输入。例如,考虑线性搜索和二分搜索。如果要搜索的元素恰好是列表中的第一个元素,线性搜索将比二分搜索更快地找到该元素。

通过测量算法的执行时间来比较算法是非常困难的。为了克服这些问题,开发了一种理论方法来分析独立于计算机和特定输入的算法。这种方法近似改变输入大小的影响。通过这种方式,您可以看到算法的执行时间随着输入大小的增加而增加的速度,因此您可以通过检查两个算法的增长率

考虑线性搜索。线性搜索算法将键与数组中的元素顺序进行比较,直到找到键或数组耗尽。如果键不在数组中,则需要对大小为 n 的数组进行 n 比较。如果键在数组中,则平均需要 n/2 次比较。该算法的执行时间与数组的大小成正比。如果将数组大小加倍,则比较次数也会加倍。该算法以线性速率增长。增长率的数量级为n。计算机科学家使用大 O 符号来表示“数量级”。使用这种表示法,线性搜索算法的复杂度为 O(n),发音为“n阶”。我们将时间复杂度为 O(n) 的算法称为线性算法,并且它呈现出线性增长率。

对于相同的输入大小,算法的执行时间可能会有所不同,具体取决于输入。导致执行时间最短的输入称为最佳情况输入,导致执行时间最长的输入称为最坏情况输入。最佳案例分析和
最坏情况分析是分析算法的最佳情况输入和最坏情况输入。最好情况和最坏情况分析不具有代表性,但最坏情况分析非常有用。您可以放心,该算法永远不会比最坏情况慢。
平均情况分析尝试确定相同大小的所有可能输入之间的平均时间量。平均情况分析是理想的,但很难执行,因为对于许多问题来说,很难确定各种输入实例的相对概率和分布。最坏情况分析比较容易进行,所以一般都是针对最坏情况进行分析。

如果您几乎总是在查找列表中已知的内容,则线性搜索算法在最坏情况下需要 n 次比较,在平均情况下需要 n/2 次比较。使用 Big O 表示法,两种情况都需要 O(n) 时间。乘法常数 (1/2) 可以省略。算法分析的重点是增长率。乘法常数对增长率没有影响。 n/2 或 100_n_ 的增长率与 n 相同,如下表 增长率 所示。因此,O(n) = O(n/2) = O(100n).

Image description

考虑在 n 个元素的数组中查找最大数字的算法。如果n为2,则需要比较一次才能找到最大数;如果n为3,则进行两次比较。一般来说,需要 n - 1 次比较才能找到 n 个元素列表中的最大数量。算法分析适用于大输入量。如果输入量很小,那么估计算法的效率就没有意义。随着 n 变大,表达式 n - 1 中的 n 部分在复杂性上占主导地位。大 O 表示法允许您忽略非主导部分(例如,
中的 -1 表达式 n - 1)并突出显示重要部分(例如,表达式 n - 1 中的 n)。因此,该算法的复杂度为O(n)。

Big O 表示法根据输入大小估计算法的执行时间。如果时间与输入大小无关,则该算法被称为采用恒定时间,符号为O(1)。例如,检索数组中给定索引处的元素的方法
需要常数时间,因为时间不会随着数组大小的增加而增加。

以下数学求和在算法分析中通常很有用:

Image description

时间复杂度是使用 Big-O 表示法来衡量执行时间。同样,您还可以使用 Big-O 表示法来测量空间复杂度空间复杂度衡量算法使用的内存空间量。书中介绍的大多数算法的空间复杂度都是 O(n)。即,它们对输入大小表现出线性增长率。例如,线性搜索的空间复杂度为 O(n).

版本声明 本文转载于:https://dev.to/paulike/developing-efficient-algorithms-measuring-algorithm-efficiency-using-big-o-notation-1c1h?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何在 Jackson 序列化期间抑制空字段值?
    如何在 Jackson 序列化期间抑制空字段值?
    处理 Jackson 序列化中的空字段值Jackson 是一个流行的 Java 序列化库,提供了各种配置选项来定制其序列化行为。一种常见的情况是抑制空字段值的序列化。这可确保序列化输出中仅包含非空属性。配置 Jackson 进行空值抑制指示 Jackson 忽略 null 有两种主要方法序列化期间的...
    编程 发布于2024-12-21
  • JavaScript 如何检测浏览器选项卡活动?
    JavaScript 如何检测浏览器选项卡活动?
    使用 JavaScript 确定浏览器选项卡活动在 Web 开发中,通常需要检测浏览器选项卡是否正在活跃使用。当选项卡位于后台时,此功能可以通过暂停或优化任务来实现高效的资源分配。确定选项卡活动的一种方法是通过页面可见性 API。此 API 提供了一个简单的布尔属性 document.hidden,...
    编程 发布于2024-12-21
  • 插入数据时如何修复“常规错误:2006 MySQL 服务器已消失”?
    插入数据时如何修复“常规错误:2006 MySQL 服务器已消失”?
    插入记录时如何解决“一般错误:2006 MySQL 服务器已消失”介绍:将数据插入 MySQL 数据库有时会导致错误“一般错误:2006 MySQL 服务器已消失”。当与服务器的连接丢失时会出现此错误,通常是由于 MySQL 配置中的两个变量之一所致。解决方案:解决此错误的关键是调整wait_tim...
    编程 发布于2024-12-21
  • C++ 中数组长度有哪些限制以及如何克服它们?
    C++ 中数组长度有哪些限制以及如何克服它们?
    研究 C 中的数组长度限制 尽管 C 数组具有巨大的实用性,但对其大小施加了一定的限制。这些限制的程度取决于几个因素,即编译器、系统硬件,甚至数组的数据类型。可变长度强制与普遍看法相反, C 并没有严格执行数组长度的绝对限制。相反,它依赖编译器和系统规范来确定最大大小。这种灵活性允许根据硬件功能进行...
    编程 发布于2024-12-21
  • HTML 格式标签
    HTML 格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2024-12-21
  • 我们如何有效地将 AST 编译回可读的源代码?
    我们如何有效地将 AST 编译回可读的源代码?
    将 AST 编译回源代码将抽象语法树 (AST) 编译回源代码,通常称为“漂亮打印” ,”对于在 AST 转换后生成人类可读的代码至关重要。有两种主要方法需要考虑:保持原始代码格式或生成美观的代码。一种方法涉及向 AST 中的每个节点添加 ->compile 方法。但是,这种方法限制了生成的输出中的...
    编程 发布于2024-12-21
  • 为什么IntelliJ编译成功后显示“无法解析符号”错误?
    为什么IntelliJ编译成功后显示“无法解析符号”错误?
    尽管编译成功,IntelliJ Inspector 错误“无法解析符号”IntelliJ 用户可能会遇到令人困惑的情况,检查器标记为“无法解析符号” " 尽管编译成功,但库导入错误。向 Maven 项目添加依赖项时可能会出现此问题,如 jmime 的情况所示。原因分析IntelliJ 为其...
    编程 发布于2024-12-21
  • SSMS中T-SQL调试时如何查看表变量值?
    SSMS中T-SQL调试时如何查看表变量值?
    在调试期间查看表变量值在 SQL Server Management Studio (SSMS) 中调试 Transact-SQL (T-SQL) 代码时,检查存储在表变量中的值会很有帮助。然而,标准调试工具并没有提供直接查看表变量内容的方法。解决方案:将表变量转换为 XML此问题的简单解决方案包括...
    编程 发布于2024-12-21
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-12-21
  • 除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为的主要场景bool:语句:if、whi...
    编程 发布于2024-12-21
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSocke...
    编程 发布于2024-12-21
  • 为什么我的 PHP 脚本抛出“无法加载动态库”警告?
    为什么我的 PHP 脚本抛出“无法加载动态库”警告?
    疑难解答:PHP警告“无法加载动态库”执行PHP脚本时,可能会遇到以下错误:PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/extensions/no-debug-non-zts-2009062...
    编程 发布于2024-12-21
  • 如何使用 Eloquent 或查询生成器将多行插入数据库?
    如何使用 Eloquent 或查询生成器将多行插入数据库?
    使用 Eloquent 或 Fluent 同时插入多行此查询探讨了如何使用 Eloquent 中的单个查询将多行插入数据库(或流畅的)框架。给定的示例使用 UserSubject::where('user_id', Auth::id())->select('subject_i...
    编程 发布于2024-12-21
  • 如何在 Retrofit 中使用自定义 Gson 转换器高效提取嵌套 JSON 数据?
    如何在 Retrofit 中使用自定义 Gson 转换器高效提取嵌套 JSON 数据?
    在 Retrofit 中使用自定义 Gson 转换器提取嵌套 JSON许多 API 提供具有通用 JSON 结构的响应,其中根对象包含嵌套对象包含所需数据的“内容”字段。然而,大多数 POJO 只对“内容”字段中的数据进行建模,使得改造类型适配器无法提取并返回适当的对象。为了解决这个问题,可以开发一...
    编程 发布于2024-12-21
  • 如何使用 PHP 将字符串中的普通 URL 转换为可点击的超链接?
    如何使用 PHP 将字符串中的普通 URL 转换为可点击的超链接?
    使用 PHP 链接字符串中的 URL在 PHP 中,链接字符串中的 URL 可能是一项有用的任务,例如在文本中生成可点击链接等任务内容。一种常见的用例是将包含 URL 的纯字符串转换为具有可点击超链接的 HTML。语法:$string = preg_replace( "~[[:alph...
    编程 发布于2024-12-21

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3