目录(点击切换)
本文节选自《计算之魂》电子版:
//计算之魂//这样的百年老店,即使只考虑每天的收盘数据,也有几万个数据点,几万的三次方可是几十万亿,计算量非常大。如果你只能想出这种方法,那还没有达到五级工程师的要求,因为你还完全没有计算机科学的概念。当然,这种方法稍加改进就能快很多,于是就有了下面的方法2。方法2,做两重循环。方法1效率不高的原因是做了太多的无用功,比如当我们把区间的起点定在了位置z之后,如果已经计算了从吴到9之间的数字的总和sp,9),下次再计算从疡到9+1!之间的数字的总和S(p,q+1)时,只需要在原来的基础上再做一次加法,而不需要再来一次循环。当然有人可能会担心,这样是否需要占用额外的存储空间来保留所有的中间结果sp,9)。其实这种担心是不必要的,因为我们只需要记录这样三个中间值。第一个值是从2开始到当前位置y为止的总和So,9),因为我们接下来计算sS(,9+1)时要用到它。第二个值则是从忆开始到当前位置4为止所有总和中最大的那个值,我们假定为Mar。有了这个值之后,如果Sp,g+D三Mar,则Warx维持不变;如果Sp,g+l)>Mar,则要更新Mar,当然,我们也要记录下来Mar是在区间[z,4+
吴军 计算机之魂
1]取得因此,第三个要记录的值就是区间结束的位置,我们不妨以~来表示。如果Mar的值更新了,相应的区间结束位置也要更新为v+1。我们不妨看这样一个具体的例子。假定区间的起始点是p=500,这时8(500,500)=asxo,Max=asoo,盖500。接下来,遇到了第501个数字,如果as>0,显然8(500,501)>8(500,500),于是记下到当前为止最大的区间总和Max=8(500,501),r=501;如果ai和0,我们知道到当前为止最大的区间总和依然是Max=8(500,500),不需要做任何改变。和雪往后,遇到第502个数字时,我们只需算出8S(500,502),如果8(500,502)>Max,则更新Warx,并且记录下王502,否则维持原来的Max和7r,然后继续往036/第1章//毫厘干里之差一一大O概念//后扫描。对于给定的忆,需要从头到尾试玉p次,也就是OG)的复杂度。而忆可以从1到天,有天种可能性,二者的组合就是O(&)。如果玉有好几万,计算量是十几亿,而方法1的计算量是它的上万倍。如果你能想到这种方法,那就基本上达到了五级工程师的要求,因为你已经搞清楚
计算之魂吴军电子版
哪些计算是重复计算了。当然,O(&)的答案远非最优,这个问题还有复杂度更低的解法。方法3,利用分治(Divide-and-Conquer)算法。关于分治算法,后面会详细介绍,这里先简单介绍一下如何在这个问题中应用分治算法。先,将序列一分为二,分成从1到馈220,以及从矶2+1到天两个子序列。然后,我们对这两个子序列分别求它们的总和最大区间。接下来有两种情况。1,前后两个子序列的总和最大区间中间没有间隔,也就是说,前一个子序列的总和最大区间是[p,&/2],后一个总和最大区间恰好是[多2+1.9]。如果两个区间各的和均为正整数,这时,整个序列总和最大区间就是P,g];否则,就选取两个子序列的总和最大区间中大的一个。2,前后两个子序列的总和最大区间中间有间隔,我们假定这两个子序列的总和最大区间分别是[pua]和[pg]。这时,整个序列的总和最大区间是下面三者中最大的那一个:3(2)[pz9;];《3)[piga]。至于为什么,这是本节的思考题。上述三个区间的总和,前两个是已经计算出的,第三个其实是对从qi+1到疡+1中《如果天是奇数,在计算机中计算出的蕊2其实是(K-1)/2。037
计算之魂 电子版
| 计算之魂mobi | 计算之魂百度网盘 |
| 计算之魂人和计算机对信息编码的差异 | 吴军计算之魂发布会 |
| 吴军计算之魂哪里可以买到 | 计算机之魂 |
综上:计算之魂吴军笔记值得推荐阅读

评论已关闭!