为什么我喜欢用C++写算法
这里只讨论算法,不讨论应用开发。其次,这里只讨论matlab、C,C++,不讨论其他语言(因为我不会)。算法,肯定是特定问题的解法,而我接触的算法,大都来自于通信、图像、模式识别领域,其他的没有接触过,不敢多做评价。做算法前,肯定会有很长的“前戏”:举个例子,在做视频的算法时,肯定免不了视频的解码,拿到一幅图像,甚至到了拿到一个像素,才是开始算法本身的工作。而这些工作,对于专注于某个算法的人来说,应该是透明的。而且我相信能独立的编写出从读取视频到获取像素的全部程序的人也不是很多。
对于很多科研人员,他们熟悉的编程工具是matlab。因为matlab提供了强大的函数库,使得复杂的数学运算(尤其是矩阵运算(奇异值分解、插值等等))、图像处理、模式识别等基本算法能够通过函数调用来完成,使得自己能够专注于问题,提出改进的思路。而且对于图像、视频,提供的读写函数自动完成了编解码操作,让我们可以专注于算法本身,跳过前戏。但是这个工具也有很多我不喜欢的地方,首先是处理速度实在是太慢了,有些时候当我们希望验证算法的实时性的时候,它就被扔到了一边。
对于另一些人,C语言是他们编写算法程序的最爱。的确,算法就是一个解决问题的办法,有输入、有输出,使用函数来描述刚刚好。而且,一般对于算法的描述,也是按步骤进行的,与面向过程的思想是相符的。加上C语言较高的执行效率,的确是一种不错的选择。而且,有很多库也可以供大家使用,能让程序员直面问题,避免了算法操作的“前戏”。但是,算法本身也有一些特点,比如参数很多,导致函数的声明非常长,这一点让我觉得不爽。有时我不得不将一些参数、数据结构设为全局变量,要不然难以完成递归的操作。而全局变量,是大家都不喜欢的。
那么我为什么喜欢C++呢?首先,觉得,算法本身与运行算法的“前戏”是没有太多关系的。根据面向对象的思想,我们应该将它们分离开,这样有助于以后代码的维护。比如我编写过一个在视频中检测运动目标的程序,我是将控制视频的操作,比如起始帧、结束帧,依次读取每一幅图像等封装成了一个类,而将算法本身需要的数据结构、阈值等封装成了另一个类,甚至,对于每个像素需要的数据结构,进行了封装。这样当我们需要对算法进行修改时就非常方便了。而且由于STL库的存在,是得一些简单的问题,比如链表、队列、排序等等可以通过函数来完成而又不失高效。
也许有人对C++的语言的复杂度提出质疑:C++由面向过程的C语言,面向对象的继承、派生机制;STL库和泛型编程4大部分组成,这还不包括新版本中的内容。掌握起来本身就不是很容易,用它写算法似乎更难。但是我觉得算法本质上是基于过程的、有具体步骤的,所以我不太倾向于在具体的算法之间使用继承派生关系,更多的时候,只是将算法与算法所操作的数据进行封装,这更像是一种基于对象的思路(带类的C语言)。而泛型编程在算法中的使用可能也不是很广泛吧,特定算法要处理的数据类型往往是确定的,不太可能出现“泛型”问题。而STL库,不仅不会提高算法的复杂度,反而是降低了算法的复杂度:对于需要依赖于一些数据结构的算法,STL提供了这些结构的模板;对于算法中的查找、排序等操作,STL库提供了高效的函数可以调用。最主要的是,STL提供了统一的泛型接口,是得他掌握起来非常容易!
最后,从工作的角度考虑。对于一个算法,一个人能用matlab写出来,另一个人能用c++写出来,如果你是老板,你会要谁呢?我的一位网友在一家搞图像的公司工作,给我说过一件事:他公司最近辞退了若干名图像方向的博士!原因就是他们只会matlab。因为,为了能配合他们工作,还得再招聘一些会C++的人,才能把它们的研究成果应用于公司实际的项目中,这样的人力资源成本实在是太高了。
国内的企业,真正能在理论方面有创新的本来就不多,所以除了一些大型的企业外,恐怕很少有公司配备专门的算法团队,让你用matlab进行仿真,找另外一批人来实现你的创新算法。更多的时候,如果你真有理论上的改进,那么你得自己实现。所以,也许使用C++是更好的选择。