我有一个比较普遍的问题。作为程序员,除了在学校之外,你是否曾经需要真正计算(例如在纸上)算法的复杂度?如果是的话,请举个例子。
谢谢 :)
我有一个比较普遍的问题。作为程序员,除了在学校之外,你是否曾经需要真正计算(例如在纸上)算法的复杂度?如果是的话,请举个例子。
谢谢 :)
在工作中,我们会随意地讨论各种算法来解决问题,并且复杂度会起到作用。我们从不需要对复杂度进行严格的证明,只是一般性地认为“我们可以做X,但这将是O(N^2),因为我们可能要遍历数百万行。”
过度优化可能导致糟糕的代码,但了解基本算法的复杂度在确定最佳解决编程问题的方法方面有很大帮助。
我不知道自己是否真的会把事情写下来,但我一直在评估我的算法构建方式,看看能否提高其效率。对于代码,我会问自己是否有办法将嵌套循环转换为单个循环或从循环转换为使用分治方法。这相当于从O(N2)到O(N)和从O(N)到O(log2N)。SQL也是如此--我能否删除一个连接并使用索引代替子查询--也许从O(N2)到O(N)(甚至是O(1),如果它使我能够在两个表上进行索引查询)。
是和不是。
我在编写一个工具,将一组软件包的RPM依赖关系展开为单个链。显而易见的解决方案运行速度太慢了,所以我从记忆中挖掘出了一个来自图论课程的O(n+m)
算法。我进行了一些草稿计算,确保它真的是O(n+m)
,然后编写并投入生产 :)。
是的。
一般来说,复杂度对于草图猜测来说是显而易见的,这对于开发来说是可以接受的,直到我需要测量性能。在许多情况下,我担心的部分没问题(即,草图猜测足够好),而其他一些东西正在减慢软件的速度。在几乎所有情况下,坚持我的基本假设并稍后测量性能都是值得的。
然而,当我编写非常时间关键的代码,特别是在图形渲染方面时,我会坐下来确定算法复杂度和采用替代方法所涉及的权衡。
今天我正在使用别人的代码,但它运行得非常慢。我并不是很在意——它可能需要10分钟才能完成整个流程,但我必须查看代码以修复错误,而这个人使用了嵌套循环,在大部分循环中每次搜索相同的列表以寻找不同的元素。实质上,他已经将一个很好的数组函数(比如func(i){return records[i];})变成了一个可怕的搜索程序:
func(i)
{
for each index in records
if i==index return records[index]
next
}
实际情况比这更糟,但你可以理解这个概念。
你现在在学校学习这个的原因是为了让你看到这些结构并自动分类。你可能不需要真正地计算机或将其简化为一个漂亮的复杂度数字,但如果你现在不手动操作并且看到很多这样的代码,那么你也会像那样生成代码,而你将毫无头绪。
-Adam