|
以下内容是我阅读《Programming Pearls second Edition》后 的一些总结和个人实践的套用。 1、程序员的主要问题不一定是技术上的,更可能是心理上的: 因为他正试图解决一个错误的问题,所以他不能取得进步。 通过打破概念上的障碍,转而解决一个更简单的问题,这样 我们最终解决了问题。 2、"问题越一般话,解决起来可能也就越容易",对于编程来说, 这就意味着直接解决一个23种情况的问题,要比编写一个处 理n种情况的通用程序,然后将该程序应用到n=23时的情况 更加困难. 3、代码的开发是自顶向下的(先从一般概念开始,然后再细化 到一行一行的代码),但正确性分析是自底向上底:我们将 从个别的代码行开始,研究它们如何一起协作以解决该问题。 当你在调试、修改代码或错误的断言语句是,要完全地理解 代码,抵御那种“改变代码,只要能让她运行起来就行”的 冲动。 4、保持代码的简单性通常是正确性的关键。 断言注释{}伪码例子(作者分析): (断言:输入、程序变量以及输出之间的关系描述了程序的 状态;断言允许程序员精确的说明这些关系。) David Gries的咖啡罐问题。起初给你提供一个盛装了一些 黑豆和白豆的咖啡罐以及一大堆额外的黑豆。然后你重复进 行以下过程,直到罐中只剩下一粒豆子为止: 随机从罐中选择两粒豆子。如果它们颜色一样,就将它们扔 掉,并且在罐中放入一粒黑豆。如果它们颜色不一样,则将 白豆放回罐子,同时扔掉黑豆。 请证明该过程会终止。当一开始罐子里既有黑豆又有白豆是, 你能说出罐子里最后剩下的豆子是什么颜色的吗? m:表示罐子里黑豆子的个数 n:表示罐子里白豆子的个数 简写形式sameColor()表示从罐中取出两粒豆子颜色相同 m=黑豆子数 n=白豆子数 {(m+n)>0} loop if (m+n)==1 {m==1 n==1} if m==1 {m==1} color=block;break else {n==1} color=whrite;break case sameColor()==black: {sameColor()==black && m>=2} m=m-1; {(m+n)>=1} sameColor()==whrite: {sameColor()==whrite && n>=2} n=n-2; {n>=0} m=m+1; {(m+n)>=1} sameColor()==false: {sameColor()==false && n>=1 && m>=1} m=m-1 {(m+n)>=1} {(m+n)>=1} 分析:循环终止时color将被赋值,在case中三种情况都会使罐 子中的豆子总数(m+n)减少一个,在初始使(m+n)>0,所以最 后罐子中肯定剩余一个豆子,m==1或n==1,可以使程序终止; 5、简单而且功能强大的程序可以让用户高兴并且也不会让程序构建 者烦恼,这是程序员的终极目标。 6、对实时软件系统进行性能计算时,我们必须按照2、4或6的系数 降低性能,以补偿我们的无知。在进行可靠性/可用性承诺时, 我们应该对我们认为能够满足的目标保留一个10的系数,以补偿 我们的无知。在估计鬼迷、成本以及进度时。我们应该保留2或4 的系数,以弥补我们在某个方面的缺漏。 爱因斯坦明言“任何事都应该做到尽可能的简单,除非没有更简 单的了” 7、分治法:要解决规模为n的问题,可递归解决两个规模近似为n/2 的子问题然后将他们的答案进行合并以得到整个问题的答案。 8、一个二分查找算法优化的例子: 算法一: l=0;u=n-1 loop /*查找t在x[l..u]中的位置*/ if l>u p=-1;break file://查找结束,t不存在x[l..u]中 m=(l+u)/2 file://二分x[l..u] case x[m]<t: l=m+1 x[m]==t:p=m;break x[m]>t: u=m-1 算法二:(优化后的算法) l=-1;u=n while l+1!=u m=(l+u)/2 if x[m]<t l=m else u=m p=u if p>=n x[p]!=t p=-1 file://t不存在x[l..u]中
上一篇:ArrayDeletor
下一篇:寒到绝对零度的一篇文章《BCB6.0是垃圾的二十条理由》
|