《C语言点滴》一1.4 程序=数据结构+算法

本节书摘来自异步社区《C语言点滴》一书中的第1章,第1.4节,作者 赵岩,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.4 程序=数据结构+算法

C语言点滴
程序员首先要有自己的想法,而写程序只是为了实现自己的想法而已。

而程序员的想法就是用数据结构+算法来描述的。如果程序是一个人,正确的数据结构就像是强壮的体格,高效的算法就像是高尚的性格,而语言,只是一件外衣而已。不同的场景,你会穿不同的外衣,而且外衣可能还有一定的流行趋势,但这些真的不重要。

纠结于语言的程序员,就像是只关注外衣是否漂亮的小姑娘。凡是能够流传千古的作品,你会发现都是不穿衣服的,如图1-10所示的罗丹的思想者;更有甚者,不仅衣服没有了,就连两个胳膊都是多余的,如维纳斯。


cf357b4f94b536800dd22b41e67cefd2a809f8c0

图1-10 就是因为熬夜,我的衣服忘记放哪了

1.4.1 数据结构

数据结构是任何计算机专业的必修课,但是目前有些程序员越来越不重视它。不重视它并不是因为它不重要,而是目前市面上两种主流的面向对象高级语言C++和Java中,都包含比较完整的基本数据结构的库实现,它们分别是C++中的Standard Template Library(STL)库和Java中的Container类。对用户来说,只要直接拿来使用就可以了。

为了使某种特定的数据结构能够支持所有的数据类型,C++和Java分别使用了两种泛型技术,分别是C++的模板技术和Java中面向对象的继承技术,如程序1-1所示。

在Java中,所有的数据类型都继承于Object,同时ArrayList支持装入任何继承于Object的数据类型,用一句俗话讲就是:“ArrayList是一个筐,乱七八糟都可以装。”不过需要注意,从ArrayList中取出数据的时候需要转换回正确的原始类型,如果没有转换回原始的类型,运行时就会出错,同时转换也有一定的效率损失。


977e63131671e7580417437f1ac1e62dea5f1635

C++的模板技术就没有类似的问题。你在声明一个vector对象的时候,必须如程序1-1中第6行所示,指定它要保存的数据类型为int,以后这个v1只能存入你指定的数据类型int了。对于模板技术,C++的STL无疑是模板技术的杰出代表,目前它已经成为C++语言标准的一部分,可见确实不同凡响。对于STL有三层境界,第一层为会用STL,大家可以参考《Effective STL》1。第二层为明白其中的原理,对应的参考书为《STL源码剖析》2。借用书中的一段话为:“源码之前,了无秘密”,确实如此。第三层为能扩充STL,这个层次就需要你自己来写本参考书了。

关于泛型技术的模板实现和继承实现,也有很多优劣的争论。吵架这种事通常我都会躲得很远,这次我依然不例外。值得注意的是,新版的Java也支持模板技术。你需要根据特定的场合来决定使用哪种方法。

有趣的是,当有人在热烈争论模板好还是继承好的时候,还有些工程师却在认真地思考,最终他们写出了这样的C++语句:class String: public Array<char,String>。这种混合使用继承和模板的技术详细的讨论可以参考《ATL Internals》3的Appendix A。利用模板可以避免继承中动态绑定的效率代价。利用继承可以提供模板技术不能提供的多态行为,这种思想可谓鱼和熊掌兼得。基于这种思想,微软建立了一套用于快速开发组件(COM)的Active Template Library(ATL)。可见,少批评、多借鉴、多思考才是我们对待不同技术的正途。

虽然有了很多优秀的数据结构库实现,但是我们还需要认真学习数据结构的基本知识和思想。现实世界中的问题往往比较复杂,很难用一两种基本的数据结构来模拟和解决,往往需要你综合利用各种基础的数据结构。同时,用户的需求千变万化,千差万别,有的时候需要你构造一个全新的数据结构才行。这些都要求你有扎实的数据结构基础知识。

1.4.2 算法

算法到底是什么?以下是Wikipedia的定义:an effective method expressed as a finite list of well-defined instructions for calculating a function. In simple words an algorithm is a step-by-step procedure for calculations。如果你不明白也没关系,其实我也不明白。算法本身就没有一个准确的、排它性的定义,正可谓:“道可道,非常道!”

你可以不知道算法的准确定义,但是一定要知道算法很重要。算法是计算机科学的核心,如果没有算法,计算机几乎不配再称为科学。虽然计算机语言和开发平台日新月异,但万变不离其宗的还是那些算法和理论。是否精通算法是菜鸟和老手的区别,也是低薪和高薪的区别。IT领域500强公司面试基本上都是算法题。算法也是区分一般任务和艰巨任务的一个指标。一般任务就是指做一个网站,只会给你3千块钱,是产业链的低端;而艰巨任务就是指解决北京的交通问题,国家会给你10个亿的。但是这种问题,绝对是一个算法密集性问题。

描述算法有两种方法,一种是利用流程图方式,如图1-11所示。


b2fbdd1f8277f6e68180df2cf88e2c31bdb8a89e

图1-11 算法流程图描述

这个算法是我最钟爱的一个算法,每当生活中出现一些烦心事,这个算法都能给我终极的答案。这就是一个好的算法的威力所在。

另外一种描述算法的方法是基于伪代码方式,如图1-12所示。比起流程图,它更加精练,也更贴近实现算法的代码,所以目前伪代码的表示方式应用得比 较广。


6e5e98d011e0207087b264f3ed13394b95fa9a2e

图1-12 Algorithm 1

你想知道Algorithm 1是怎么生成的吗?其实我早就等你问这个问题了!首先它不是画出来的,而是自动生成的。它是用LaTeX软件并利用了algorithm2e.sty包编写完成的。生成Algorithm 1的Latex源码内容如图1-13所示。有了LaTeX下这些功能扩展包,撰写计算机语言的书籍变得如此便捷和充满乐趣。有关LaTeX的一本经典参考书是4。

LaTeX与Word是目前两种主流的文本编辑系统,在使用便捷性和学习难度上,Word明显优于LaTeX,这点从Algorithm 1的LaTex源码上你就能有所体会。仅“所见即所得”一项,LaTeX就弱爆了。但如果应用在学术报告、科技论文以及教材方面,Word就有些力不从心了。至少如此美观、整齐的Algorithm 1,利用Word是很难高质量、大批量地生成出来。关于LaTeX与Word的区别,大家可以参考本书网站上“扩展内容”网页中的“LaTex和Word的不同”。


5fcabbfa67cb8d2a603a117a3608ea3233601fcf

图1-13

LaTeX是基于TeX的一个排版系统,TeX是一个很好的排版工具,特别是在处理复杂的数学公式时。提起TeX,就必须提到它的开发者、大名鼎鼎的美国计算机教授高德纳(Donald E. Knuth)。高教授还撰写了《The Art of Computer Programming》一套书,计划写7卷,目前完成了前4卷。本套书在1999年底被美国国家期刊(American Scientist)列为20世纪最佳12部学术专著之一,与狄拉克的量子力学、爱因斯坦的相对论齐名。

在中国,本书被称为算法领域的“葵花宝典”。光凭“葵花宝典”这个比喻,就已经吓得我直到现在都没有胆量去读。所以我选择了一本相对初级的“独孤九剑”来读,那就是《算法导论》5。等以后我的功力增长到一定程度,再和媳妇商量商量,然后再去读“葵花宝典”。

算法很有用,但是,算法真的很难学,需要一些抽象的思维和数学基础,不是一朝一夕就能搞定的。我的建议是,如果你立志当一名程序员,就要把学算法、用算法当成毕生的事情,所以我们的口号就是:“随时随地快乐学”。记住,任何一本算法书都应该随时、随地拿来读,不要指望着几天读完了事、收工。

1Scott Meyers. Effective STL. 北京:中国电力出版社,2003
2侯捷. STL源码剖析. 武汉:华中科技大学出版社,2002
3Christopher Tavares. ATL Internals: Working with ATL 8. Addison-Wesley Professional,2006
4Frank Mittelbach. The Latex Companion. Addison Wesley,2004
5Cormen T.H. 算法导论. 北京:机械工业出版社,2006

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值