我的C语言/C++算法学习之路

C语言是面向过程的,而C++是面向对象的

这些是C/C++能做的

服务器开发工程师、人工智能、云计算工程师、信息安全(黑客反黑客)、大数据、数据平台、嵌入式工程师、流媒体服务器、数据控解、图像处理、音频视频开发工程师、游戏服务器、分布式系统、游戏辅助等

一、关于

严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口——况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以我认为本文题目是合理的。

我这些年学习数据结构和算法的总结。

一些不错的算法书籍和教程。

算法的重要性。

二、初学

第一次接触数据结构是在大二下学期的数据结构课程。然而这门课程并没有让我入门——当时自己正忙于倒卖各种MP3和耳机,对于这些课程根本就不屑一顾——反正最后考试划个重点也能过,于是这门整个计算机专业本科最重要的课程就被傻逼的我直接忽略过去了。

直到大三我才反应过来以后还要找工作——而且大二的折腾证明了我并没有什么商业才能,以后还是得靠码代码混饭吃,我当时惊恐的发现自己对编程序几乎一无所知,于是我给自己制订了一个类似于建国初期五年计划的读书成长计划,其中包括C语言基础、数据结构以及计算机网络等方面的书籍。

读书计划的第一步是选择书籍,我曾向当时我觉得很牛的“学长”和“大神”请教应该读哪些算法书籍,”学长”们均推荐算法导论,还有几个”大神”推荐计算机程序设计艺术(现在我疑心他们是否翻过这些书),草草的翻了下这两本书发现实在看不懂,但幸运的是我在无意中发现了豆瓣这个神奇的网站,里面有很多质量不错的书评,于是我就把评价很高而且看上去不那么吓人的计算机书籍都买了下来——事实证明豆瓣要比这些”学长”或是”大神”靠谱的多得多。

2.1数据结构与算法分析——C语言描述

数据结构与算法分析——C语言描述是我学习数据结构的第一本书:当时有很多地方看不懂,于是做记号反复看;代码看不明白,于是抄到本子上反复研读;一些算法想不通,就把它所有的中间状态全画出来然后反复推演。事实证明尽管这种学习方法看起来傻逼而且效率很低,但对于当时同样傻逼的我却效果不错——傻人用傻办法嘛,而且这本书的课后题大多都是经典的面试题目,以至于日后我看到编程之美的第一反应就是这货的题目不全是抄别人的么。

至今记得,这本书为了说明算法是多么重要,在开篇就拿最大子序列和作为例子,一路把复杂度从O(N^3)杀到O(N^2)再到O(NlgN)最后到O(N),当时内心真的是景仰之情如滔滔江水连绵不绝,尼玛为何可以这么屌,

此外,我当时还把这本书里图算法之前的数据结构全手打了一遍,后来找实习还颇为自得的把这件事放到简历里,现在想想真是傻逼无极限。

凭借这个读书成长计划中学到的知识,我总算比较顺利的找到了一份实习工作,这是后话。

三、入门

我的实习并没有用到什么算法(现在看来就是不停的堆砌已有的API,编写一堆自己都不知道对不对的代码而已),在发现身边的人工作了几年却还在和我做同样的事情之后,我开始越来越不安。尽管当时我对自己没什么规划,但我清楚这绝壁不是我想做的工作。

3.1微软的梦工厂

在这个摇摆不定的时刻,微软的梦工场成了压倒骆驼的最后一支稻草,这本书对微软亚洲研究院的描写让我下定了“找工作就要这样的公司”的决心,然而我又悲观的发现无论是以我当时的能力还是文凭,都无法达到微软亚研院的要求,矛盾之下,我彻底推翻了自己”毕业就工作”的想法,辞掉实习,准备考研。

考研的细节无需赘述,但至今仍清楚的记得自己在复试时惊奇且激动的发现北航宿舍对面就是微软西格玛大厦,那种离理想又进了一步的感觉简直爽到爆。

3.2算法设计与分析

我的研究生生涯绝对是一个反面典型——翘课,实习,写水论文,做水研究,但有一点我颇为自得——从头到尾认真听了韩军教授的算法设计与分析课程。

韩军给我印象最深的有两点:课堂休息时跑到外面和几个学生借火抽烟;讲解算法时的犀利和毫不含糊。

尽管韩军从来没有主动提及,但我敢肯定算法设计与分析基础就是他算法课程事实上的(de-facto)教材,因为他的课程结构几乎和这本书的组织结构一模一样。

如果数据结构与算法分析——C语言描述是我的数据结构启蒙,那么韩军的课程算法设计与分析基础就是我的算法启蒙,结合课程和书籍,我一一理解并掌握了复杂度分析、分治、减治、变治、动态规划和回溯这些简单但强大的算法工具。

3.3算法引论

算法引论是我这时无意中读到的另一本算法书,和普通的算法书不同,这本书从创造性的角度出发——如果说算法导论讲的是有哪些算法,那么算法引论讲的就是如何创造算法。结合前面的算法设计与分析基础,这本书把我能解决的算法问题数量扩大了一个数量级。

之后,在机缘巧合下,我进入微软亚洲工程院实习,离理想又近了一步,自我感觉无限牛逼。

四、巩固

在微软工程院的实习是我研究生阶段的一个非常非常非常重要的转折点:

做出了一个还说的过去的小项目。

期间百度实习面试受挫,痛定思痛之下阅读了大量的程序设计书。

微软的实习经历成为了我之后简历上为数不多的亮点之一(本屌一没成绩,二没论文,三没ACM)。

这里就不说1和3了(和本文题目不搭边),重点说说2。

然而一件事打断了这段安逸的生活——

4.1百度实习面试

这件事对我产生了很大的震动——

原来自己连百度实习面试都过不去。

原来自己还是一个编程弱逼。

原来自己还是一个算法菜逼。

4.2ElementsofProgramming

由于一直觉得名字里带“Elementsof”的都是酷炫叼炸天的书,所以我几乎是毫不犹豫的买了这本ElementsofProgramming(中译本:编程原本),事实上这本书里的代码(或者说STL的代码)确实是:快,狠,准,古龙高手三要素全齐。

4.3CInterfacesandImplementation

严格来说上面两本书都不是传统的算法书,因为它们侧重的都不是算法,而是经典算法的具体实现(Implementation),然而这正是我所需要的:因为算法的原理我能说明白,但要给出优雅正确简练的实现我就傻逼了,哪怕是stof这种简单到爆的“算法”。

依然是以前的傻逼学习方法:反复研读+一遍又一遍的把代码抄写到本子上,艰难的完成了这两本书后,又读了相当数量的编程实践(ProgrammingPractice)书籍,自我感觉编程能力又大幅提升,此外获得新技能——纸上编码。这也成为了我之后找工作面试的三板斧之一。

五、应用

所以那些动则就扯什么算法啊基础啊内功啊所谓的大牛们,请闭上你的嘴,条条大道通罗马。算法并不是编程的前提条件,数学也不会阻碍一个人成为优秀的程序员。至少在我看来,什么算法基础内功都是唬人的玩意,多编点能用的实用的程序才是王道,当然如果你是一个puretheorist的话就当我什么都没说好了。

5.1LL(k)

我在微软实习的第一个项目做的是代码覆盖率分析——计算T-SQL存储过程的代码覆盖率。

阅读了块覆盖的定义后,我发现我需要对T-SQL进行语法分析,在没有找到一个好用的T-SQLParser的情况下,只能自己动手搞一个:

LanguageImplementationPatterns

比较奇诡的是,做这个项目时当时我刚好把ANTLR作者的LanguageImplementationPatterns(中译本:编程语言实现模式)看了一半,什么LL(k)啊Packrat啊ASTWalker的概念啊正热乎着呢。

于是,自己自己就照着T-SQL的官方EBNF,三下五除二搞了一个T-SQL存储过程的LL(k)Parser,把代码转换成AST,然后用一个ExternalASTWalker生成代码块覆盖的HTML报表,全部过程一周不到。

老大自然是很满意——我疑心他的原计划是花两三个月来完成这个项目,因为这个项目之后的两个月我都没什么活干,天天悠哉游哉。

5.2拼音索引

拼音索引是我接的一个手机应用私活里的小模块,用户期待在手机文本框可以根据输入给出智能提示:

比如说输入中国:

同样,输入拼音也应给出提示:

痛骂MS坑爹+汉字坑爹之余,还是得自己撸一个库出来:

首先把那两万个汉字搞了出来,排序,然后弄成一个超长的字符串。

接下来用Int16索引了汉字所有的拼音(貌似500多个)。

再接下来用Int64建立汉字和拼音的关联——汉字有多音字,所以需要把多个拼音pack到一个Int64里,这个简单,位操作就搞定。

最后用二分+位移Unpack,直接做到从汉字到拼音的检索。

后来小测了下性能,速度是MS原来那个库的五十倍有余,而代码量只有336行。

用户很happy——因为我捎带把他没想到的多音字都搞定了,而且流畅的一逼。

我也很happy,因为没想到自己写的库居然比MS的还要快几十倍,同时小十几倍。

从这个事情之后我变得特别理解那些造轮子的人——你要想想,如果你需要一个飞机轮子但市场上只有自行车轮子而且老板还催着你交工,你能怎么搞。

5.3快速字符串匹配

前面提到在微软实习时老大扔给我一个WindowsPhone让我研究下,我当时玩了玩就觉着不太对劲,找联系人太麻烦。

比如说找”张晓明”,WP只支持定位到Z分类下——这意味着我需要在Z分类下的七十多个联系人(姓张的姓赵的姓钟的等等)里面线性寻找,每次我都需要滑动四五秒才能找到这个张姓少年。

这也太傻逼了,本屌三年前的老破NOKIA都支持首字母定位,996->ZXM->张晓明,直接搞定,尼玛一个新时代WindowsPhone居然会弱到这个程度。

搜了一下发现没有好用的拨号程序,于是本屌就直接撸了一个支持首字母匹配的拨号程序出来扔到WP论坛里。

结果马上就有各种问题出现——最主要的反映是速度太慢,一些用户甚至反馈按键有时要半秒才有反应。本屌问了下他的通讯录大小:大概3000多人。

吐槽怎么会有这么奇葩的通讯录之余,我意识到自己的字符串匹配算法存在严重的性能问题:读取所有人的姓名计算出拼音,然后一个个的匹配——结果如果联系人数量太多的话,速度必然拙计。

于是我就开始苦思冥想有没有一个能够同时搜索多个字符串的高端算法,以至于那两天坐地铁都在嘟囔怎么才能把这个应用搞的快一些。

最终还是在AlgorithmsonStrings,TreesandSequences里找到了答案——确实有能够同时搜索多个字符串的方法:Tries,而且这本书还用足足一章来讲怎么弄Multiplestringcomparison,看得我当时高潮迭起,直呼过瘾。

具体细节不多说,总之换了算法之后,匹配速度快了大约九十多倍,而且代码还短了几十行。哪怕是有10000个联系人,也能在0.1秒内搞定,速度瓶颈就这样愉快的被算法搞定。

5.4WritingEfficientPrograms

之后又做了若干个项目,多多少少都用到了”自制”的算法或数据结构,最奇诡的一次是写一个电子书阅读器里的分页,我照着模拟退火(SimulatedAnnealing)的原理写了一个快速分页算法,事实上这个算法确实很快——但问题是我都不知道为啥它会这么快。

总之,算法是一种将有限计算资源发挥到极致的武器,当计算资源很富余时算法确实没大用,但一旦到了效率瓶颈算法绝壁是开山第一刀(因为算法不要钱嘛!要不还得换CPU买SSD升级RAM,肉疼啊!!)。一些人会认为这种说法是有问题,因为编写新算法的人力成本有时比增加硬件的成本还要高——但别忘了增加硬件提升效率也是建立在算法是Scalable的基础上——说白了还是得搞算法。

说到优化这里顺带提一下WritingEfficientPrograms——很难找到一本讲代码优化的书(我疑心是自从Knuth说了过早优化是万恶之源之后没人敢写,万恶之源嘛,写它干毛),注意这本书讲的是代码优化——在不改变架构、算法以及硬件的前提之下进行的优化。尽管书中的一些诸如变量复用或是循环展开的trick已经过时,但总体仍不失为一本好书。

六、提高

实习实习着就到了研二暑假,接下来就是求职季。

求职季时我有一种莫名的复仇感——尼玛之前百度实习面试老子被你们黑的漫天飞翔,这回求职老子要把你们一个个黑回来,尼玛。

现在回想当时的心理实属傻逼+幼稚,但这种黑暗心理也起了一定的积极作用:我丝毫不敢有任何怠慢,以至于在5月份底我就开始准备求职笔试面试,比身边的同学早了两个月不止。

我没有像身边的同学那般刷题——而是继续看书抄代码学算法,因为我认为那些难得离谱的题面试官也不会问——事实上也是如此。

6.1AlgorithmDesignManual

因为很多CodingInterview的论坛都提到这本红皮书,我也跟风搞了一本。事实证明,仅仅是关于BacktrackTemplate那部分的描述就足以值回书价,更不用说它的Heuristics和课后题。

6.2编程珠玑&更多的编程珠玑

这两本书就不用多介绍,编程珠玑和更多的编程珠玑,没听说过这两本书请自行面壁。前者偏算法理论,后者偏算法轶事,前者提升能力,后者增长谈资,都值得一读。

6.3TheScienceofProgramming

读到编程珠玑里面关于BinarySearch的正确性证明时我大呼过瘾,原来程序的正确性也是可以推导的,然后我就在那一章的引用里发现DavidGries的TheScienceofProgramming。看名字就觉得很厉害,直接搞了一本开撸。

不愧为编程珠玑引用的书籍,读完TheScienceofProgramming之后,我获得了证明简单代码段的正确性这个技能——求职面试三板斧之二。

证明简单代码段的正确性是一个很神奇的技能——因为面试时大多数公司都会要求在纸上写一段代码,然后面试官检查这段代码,如果你能够自己证明自己写的代码是正确的,面试官还能挑剔什么呢?

之后就是各种面试,总之就是项目经历、纸上代码加正确性证明这三板斧,摧枯拉朽。

七、进化

求职毕业季之后就是各种Happy,Happy过后我发现即将面临另一个问题:算法能力不足。

因为据说以后的同事大多是ACM选手,而本屌从来没搞过算法竞赛,而且知道的算法和数据结构都极为基础:像那些元胞自动机、斐波那契堆或是线段树这些高端数据结构压根只是能把它们的英文名称拼写出来,连用都没用过,所以心理忐忑的一逼。

为了不至于到时入职被鄙视的太惨烈,加上自己一贯的算法自卑症,本屌强制自己再次学习算法:

7.1算法(第四版)

算法(第四版)是我重温算法的第一本书,尽管它实际就是一本数据结构的入门书,但它确实适合当时已经快把算法忘光的本屌——不为学习,只为重温。

这本书最大的亮点在于它把Visualization和Formatting做到了极致——也许它不是最好的数据结构入门书,但它绝壁是我读过的排版最好的书,阅读体验爽的一逼;当然这本书的内容也不错,尤其是红黑树那一部分,我想不会有什么书会比此书讲的更明白。

7.26.851AdvancedDataStructures

AdvancedDataStructures是MIT的高级数据结构教程,为什么会找到这个教程呢?因为GoogleAdvancedDataStructures第一个出来的就是这货。

这门课包含各种让本屌世界观崩坏的奇诡数据结构和算法,它们包括但不限于:

带“记忆”的数据结构(DataStructurewithPersistence)。

o(lglgn)的BST。

总之高潮迭起,分分高能,唯一的不足就是没有把它们实现一圈。

八、总结

从接触算法到现在,大概七年:初学时推崇算法牛逼论,实习后鼓吹算法无用论,读研后再被现实打回算法牛逼论。

怎么这么像辩证法里的肯定到否定再到否定之否定。

现在来看,相当数量的鼓吹算法牛逼论的人其实不懂算法的重要性——如果你连用算法解决实际问题的经历都没有,那你如何可以证明算法很有用?而绝大多数鼓吹算法无用论的人不过是低水平码农的无病呻吟——他们从未碰到过需要用算法解决的难题,自然不知道算法有多重要。

PeterNorvig曾经写过一篇非常精彩的SICP书评,我认为这里把SICP换成算法依然适用:

Touseananalogy,ifalgorithmswereaboutautomobiles,itwouldbeforthepersonwhowantstoknowhowcarswork,howtheyarebuilt,andhowonemightdesignfuel-efficient,safe,reliablevehiclesforthe21stcentury.Thepeoplewhohatealgorithmsaretheoneswhojustwanttoknowhowtodrivetheircaronthehighway,justlikeeveryoneelse.

MIT教授ErikDemaine则更为直接:

Ifyouwanttobecomeagoodprogrammer,youcanspend10yearsprogramming,orspend2yearsprogrammingandlearningalgorithms.

总而言之,如果你想成为一个码农或是熟练工(CodeMonkey),你大可以不学算法,因为算法对你确实没有用;但如果你想成为一个优秀的开发者(Developer),扎实的算法必不可少,因为你会不断的掉进一些只能借助算法才能爬出去的坑里。

THE END
1.C++基础代码—20余种数据结构和算法的实现基本上可以分为两大类,一种是关于数据结构和算法的(例如:RBtree,stack),另一种是关于C++语言本身层面的(例如:reference_count,Uncopyable)。这些类,可以在如今C++标准库或者其它C++库(如:boost)中找到类似的实现,实现它们的目的不是想自己造轮子,而是通过实现,来深入的理解到一些更本质的东西。很多时候,人们往往“http://help.louzhutie.cn/?developer/article/2477584
2.算法学习笔记1语法(C++组)51CTO博客文章标签 C++ 算法学习 文章分类 数据结构与算法 人工智能 关于#include 包含printf();和scanf();c++中printf、scanf比cout、cin效率高很多算法题里cin、cout可能超时,虽然可以优化,但是优化之后还是比不上scanf和printf。第一章 算法入门及简单的顺序结构https://blog.51cto.com/u_15127589/2799861
3.数据结构+算法+c++学习(写在前面)c++和数据结构一起学数据结构+算法+c++学习(写在前面) 本篇开始将开始更新算法方面的博客,其实应该是数据结构更多一些,我不知道大家是如何学习算法和数据结构的,就我目前的学习情况,简单的和大家说一下感受。本人研一时学校开设了算法这门课程,当时上这门课时也很用心的学习了,但是那时候的学习更多的是理解各个算法的原理,不懂数据https://blog.csdn.net/weixin_42398658/article/details/87940074
4.编程竞赛宝典C++语言和算法入门希望本书的出版,能够给学有余力的中学生、计算机专业的大学生、程序算法爱好者以及IT行业从业者提供学习计算机科学的帮助。 张新华 2021年5月 第01章 C++语言入门 计算机编程语言能够实现人与计算机之间的沟通与交流,使计算机能够根据人编写的代码一步一步地工作,完成某些特定的任务。C++语言是使用最广泛的编程语言之一https://www.epubit.com/bookDetails?id=UB77a9ce8133887
5.算法学习1512.好数对的数目(java/c/c++/python/go/c++ classSolution{public:intnumIdenticalPairs(vector<int>& nums){intans =0;intcounter[101];memset(counter,0,sizeof(counter));for(auton : nums) { ans += counter[n]++; }returnans; } }; python classSolution:defnumIdenticalPairs(self, nums:List[int]) ->int: https://developer.aliyun.com/article/873167
6.支持C++,Java,Python,Go,JavaScript等多语言版本,从此算法学习《代码随想录》LeetCode 刷题攻略:200道经典题目刷题顺序,共60w字的详细图解,视频难点剖析,50余张思维导图,支持C++,Java,Python,Go,JavaScript等多语言版本,从此算法学习不再迷茫! 来看看,你会发现相见恨晚!https://portrait.gitee.com/programmercarl/leetcode-master
7.Hello算法(C++语言版)中文PDF电子书下载或者多试试几个下载地址 ☉ 如果遇到什么问题,请评论留言,我们定会解决问题,谢谢大家支持! ☉ 本站提供的一些商业软件是供学习研究之用,如用于商业用途,请购买正版。 ☉ 本站提供的Hello算法 (C++语言版) 中文PDF资源来源互联网,版权归该下载资源的合法拥有者所有。https://www.jb51.net/books/907953.html
8.编程竞赛宝典:C++语言和算法入门.pdf张新华2021年版本书以Dev-C++为C++语言的开发环境,首先带领读者入门C++语言,然后循序渐进、由浅入深地讲解C++语言的基本结构、数组、函数、指针、结构体、位运算等知识,并编排了竞赛模拟、阶段检测等内容,使读者能及时评估自己的学习效果。本书在介绍C++语言的同时,更加侧重于计算思维的培养,通过“一题多解”及“数学求解”等方法https://max.book118.com/html/2021/1129/7064142166004053.shtm
9.c语言算法培训班C++程序算法课程C++程序算法课程 中班详询 课程优势:以学生为主体、采用探究式的学习方式、个性化的学习目标和结果标准设置,赋予学生学习的自主性,辅以的课程设计和专业的授课过程 上课方式:面授 上课时段:全日制,白天班,晚班,周末班 ¥ 询价 预约试听 学习能力 设计 编程 https://www.qinxue365.com/course/648986.html
10.深度学习基于web端和C++的两种深度学习模型部署方式深度学习 Author:louwill Machine Learning Lab 本文对深度学习两种模型部署方式进行总结和梳理。一种是基于web服务端的模型部署,一种是基于C++软件集成的方式进行部署。 基于web服务端的模型部署,主要是通过RESTAPI的形式来提供接口方便调用。而基于C++的深度学习模型部署,主要是通过深度学习框架的C++前端版本,将模型集成https://cloud.tencent.com/developer/article/1684510
11.CCFPTACC++语言测试标准(2022.04更新)编程专业能力测试通过对认证参考人从事编程培训职业所需的 专业核心能力进行测试并做出评价,为编程教育从业人员提供专业发展依据,为编程学习者选择师资提供参照依据。 编程能力测试内容包括程序设计的语言、算法、简单数据结构知识,以及观察和分析问题能力、对问题抽象化模型化的能力、算法设计的程序实现能力、测试数据https://pta.ccf.org.cn/cms/show.action?code=jumpnewstemplate&siteid=100000&channelid=0000000115&newsid=922817f2a8394ed2a881e93ac763914a
12.开立生物医疗科技(武汉)有限公司2024届春季校园招聘4、良好的人际沟通能力和团队合作能力,善于学习,责任心强; 5、有二维图像处理或者三维图像处理项目/课题经验者优先。 工作职责(下述一项或多项): 1、图像处理算法设计、改进及仿真验证; 2、图像处理FPGA算法开发与定点化分析或C/C++算法实现及验证; 3、图像处理GPU算法开发与测试验证; https://cqu.cqbys.com/campus/view/id/689831