8、编程珠玑笔记八算法设计技术
本篇名言:“成大事不在于力量多少,而在能坚持多久。”
欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48420199
算法上的灵机一动可以让程序更加简单。本章作者剑走偏锋,算法一个戏剧性贡献:复杂深奥的算法有时可以极大的提高程序性能。
我们先来看下问题,如下图1:
就是求任何连续子向量中的最大和。
程序实现比较简单,但是简单程序可能很低效。
伪代码如下,有3层循环,称为立方算法,标记为算法1。
图2
稍作修改就可以变成平方算法,标记为算法2。
作者进一步进行分析。
分治算法,标记为算法3:
要解决规模为N的问题,可递归解决两个规模近似为N/2的子问题,然后对它们的答案进行合并已得到整个问题的答案。
该问题的算法3是将数组分成左右两边,那么左边得到最大向量,右边也得到最大子向量,那么最大子项量要么是左边,要么是右边,也有可能是跨越左右的子项量。当然跨越左右的子项量稍微负载一点(左边右边界最大子项量和右边左边界最大子项量的和及是)。这样复杂度变成了0(nlogn)
继续,深入得到算法四一个完全线性的算法,标记为算法4。
即扫描算法:
从数组最左端元素x[0]开始扫描,一直到最右端元素x[i-1]为止,记下所遇到的最大总和子向量。这样运行时间为O(n).图3
最后让蛤蟆惊讶的是,作者居然拿出了古董机器来计算算法四,用比较高端的机器来计算算法1. 古董计算性能比那个小机慢了整整3300万倍,但是也不能阻挡线性计算的后来居上。
这个问题看似漫不经心的,其实大有来头,最早是布朗大学的Grenander同学在1977年处理模式匹配时候搞出了算法1,自己又开发了算法2 。后来告诉了另一个同学Shamos,便开发了算法三。最后Shamos感觉天下无敌的时候去参加研讨会,现在统计学家Kadane居然在一分钟之内勾勒出了算法4.
最后作者给出了几个重要的算法设计技术。
保存状态,避免重复计算。算法2和算法4都进行保存中间结果。
将信息预处理至数据结构中。
分治、扫描等算法。
只有经过广泛的研究和实践,才能熟练地运用算法设计技术;但是大多数程序员仅仅是从有关算法的课程或教科书中获得这些知识的。