Algorithm 学习高效算法

Algorithm 学习高效算法,algorithm,complexity-theory,Algorithm,Complexity Theory,到目前为止,我主要关注的是如何正确设计代码,使其尽可能可读和可维护。所以我总是选择学习编程的更高层次的细节,比如类交互、API设计等 我从未真正发现算法特别有趣。因此,即使我能为我的程序提出一个好的设计,即使我能为给定的问题提出一个解决方案,它也很少是最有效的 是否有一种特殊的思考问题的方式可以帮助你找到一个尽可能有效的解决方案,或者是一个简单的练习和/或记忆的问题 另外,您可以推荐哪些在线资源来教您针对不同问题的各种有效算法 是一本让您思考不同算法/数据结构效率的好书 这本书的作者还在麻省理工

到目前为止,我主要关注的是如何正确设计代码,使其尽可能可读和可维护。所以我总是选择学习编程的更高层次的细节,比如类交互、API设计等

我从未真正发现算法特别有趣。因此,即使我能为我的程序提出一个好的设计,即使我能为给定的问题提出一个解决方案,它也很少是最有效的

是否有一种特殊的思考问题的方式可以帮助你找到一个尽可能有效的解决方案,或者是一个简单的练习和/或记忆的问题

另外,您可以推荐哪些在线资源来教您针对不同问题的各种有效算法

是一本让您思考不同算法/数据结构效率的好书


这本书的作者还在麻省理工学院教授算法课程。你可以发现大多数讲座

数据占主导地位。如果你围绕正确的抽象数据结构(ADT)设计你的程序,你通常会得到一个干净的设计,算法会很自然地遵循,当性能不足时,你应该能够“插入”更高效的算法

强大的数学和逻辑背景有助于这一点,因为它允许您在较高的层次上将程序可视化为函数、集合、图形、序列等之间的交互。然后,您可以决定集合是否需要排序(平衡BST、O(lg n)操作)或否(哈希表、O(1)操作),序列上需要支持哪些操作(类向量或类列表),等等

如果您想学习一些算法,请阅读Cormen等人的好书,并尝试实现主要的数据结构:

  • 二叉搜索树
  • 通用二进制搜索树(不仅仅适用于
    int
    或字符串)
  • 哈希表
  • 优先级队列/堆
  • 动态数组
建议: 首先,我推荐这本书“算法简介,科尔曼第二版”,这本伟大的书包含了你需要的大部分(如果不是全部的话)算法。(一些更重要的主题是排序算法、最短路径、动态编程、许多数据结构,如bst、哈希映射、堆)

学习算法的另一个好方法是,在开始后进行大量的练习


对于您的问题,您将习惯于编写快速运行的好代码,经过一点练习后,您就不会想编写效率低下的代码。

我想说,在提出好的算法(这实际上是好的设计IMHO的一部分)时,您必须发展一种思维方式。这最好通过研究算法设计来实现。我所说的学习并不仅仅是指了解教科书中涵盖的所有通用算法,而是要真正理解它们是如何工作的以及为什么工作的,并且能够将其中包含的基本思想应用到您试图解决的实际问题中

我建议读一本关于算法的好书(我最喜欢的是CLRS)。对于一个在线资源,我会推荐中的系列文章


我不明白你为什么同时提到练习和记忆。记忆对你毫无帮助(你可能已经知道这一点),但练习是必不可少的。如果你不能应用你学到的东西,那就不是真正的学习。您可以在各种在线编程竞赛/益智网站进行练习,如和

虽然我认为@larsmans是正确的,因为理解逻辑和数学是理解如何选择有用的ADT来解决给定问题的快速方法,但研究现有的解决方案可能对我们这些与这些主题斗争的人更有启发性。特别是,检查已建立的软件(OSS)的代码,它解决了与您感兴趣的软件类似的问题

我发现这种研究方法的一个特别好的方法是审查这样一个项目的单元测试,例如,有一个包含许多示例的源代码管理存储库。虽然它没有揭示底层算法,但它有助于跟踪解决特定问题的特定功能。这给我们提供了一个研究其内在机制的机会——即一个有趣的算法。我想到了Lucene的情况


虽然这并不能保证您发现的算法是最好的,但它很可能是一个经过大量仔细审查的算法,可能来自一个活跃的邮件项目,可能会回答您的问题。因此,这是一个很好的资源,可以找到一个可能比我们大多数人自己想出的更好的解决方案

USACO很擅长学习如何在很短的时间内解决NP完全问题,但它与软件工程中的实际问题几乎没有关系。那本书不仅仅是一本介绍书。它是连接算法设计和程序设计的+1。把克努特的“万恶之源”这句话断章取义太容易了;好的程序,甚至好的接口都应该为正确性和速度而设计。更多细节:我不是说设计模式,如何遍历树,以及其他常见的东西。我正在寻找的一个例子是:你有一个数字列表,你知道其中只有一个是唯一的(其他的都显示两次)。你必须确定O(n)中哪个是唯一的数字:你使用XOR运算。这是解决Project Euler风格问题的好方法,但是你在日常工作中遇到过这种问题吗?@larsmans我意识到这不是你在现实世界中遇到的问题,但肯定(以某种不同的形式)它有用途(对吧?)。我认为自己只需要编写逻辑就可以编写其他有效的程序,但我不擅长有效地解决这些抽象问题。(我在上高中,我没有工作。:)啊哈。嗯,一些更“奇特”的算法确实会不时出现(鸽子洞)