C、C++、MATLAB、Python、Go 哪个比较适合写算法?
程序员文章站
2022-06-15 07:58:35
...
编程背景:我不是计算机相关专业的 是以数学物理等基础学科为专业的 C语言刚刚自学看完了C primer plus,对整个语言有个初步的了解,但没有多少编程经验。 C++ 只是略略看了些类与继承的内容和OOP的思想,还没有入门。matlab不久就要学,因为在数值计算和数据可视化方面需要用到。python和Go语言完全没有接触过。
目前学编程的主要目的不是为了做项目或者找工作或者写paper,而是打算用《算法导论》这书学算法的时候写程序实现一下,或者对一些感兴趣的事情建模分析。对于算法,我比较在意的不是具体实现的细节,而是背后的思想和数学原理。
我听说C/C++在写算法的时候,会花大量时间来处理和实现相关的细节上,而Java和python写算法能比较集中到算法本身的内涵上。请问的确有这种情况吗?
如果python或者Go比较适合写算法,请问下像我这样背景的人适合用什么样的书或者资料上手这些语言?
如果C/C++写算法比另外几种语言要更合适,那C和C++在这方面具体的区别是什么?我有需要再额外学习C++,还是继续深入锻炼C语言的能力?
第一次在知乎上提问,感谢!
学《算法导论》的核心目标之一是建立起对算法复杂度的全面理解和感受,这当然要在一个容易对性能建模/预测的系统上实验比较好,比如C/C++这些runtime基本不做什么额外操作的“纯被动”的高度可预测的系统。你选择一个有managed Memory/IO的系统,结果字面上的O(1)操作其实背后有时不是O(1)的,那你不等于自寻困扰么
你想对感兴趣的事情建模分析,这是数学或是其他学科的范畴。这时当然用高级的工具比较好。别的不说,单单做个整数数值计算还要考虑数值太大了会不会溢出这些机器层次上的问题不是浪费时间么
首先,没泛型的语言未必工作不好用,我司现在服务端代码几乎都是go,但是没有泛型,写通用的代码就是不好用。我用Go把半本《算法》实现了一遍,移植了Haskell 的 Parsec 库。这些代码大部分都在我团队的项目里实际使用。你要说 Go 有多熟练未必,但是要说它在语言功能上有多少坑我倒是挺熟悉。没泛型的话算法实现起来太坑人了,别的不说 float32/float64/int8/int16/int32/int64/int 这些数值类型你能都覆盖么?如果只是基于某一组有限的数据类型和问题领域实现一遍,用 go 倒是不错,它环境配置容易,不太依赖ide,但是对ide还是比较友好的,天然集成test,编译快速,模型简单,学习容易,可以说是我用过的静态编译型语言里最像动态脚本语言,最适合快速开发微型工具的。
其次,Python/Ruby 这类语言其实不太适合练习算法实现,它们太“高级”了。例如用Python的时候,你很难规避它的内置容器List和Dict,这些东西封装了太多东西,在学习的过程中容易被干扰。另外没有静态的类型控制,在学习过程中也会失去一些知识。倒不是就会导致你后半生这部分都不能自理,但是需要另外学习。
在我的经验,要学习算法,C++/C#/Java 仍然是比较好的选择,它们的泛型已经比较成熟,能够在学习中建立比较完备的知识概念。可以找到一些比较好的IDE用,我个人其实在工作中不怎么用IDE,但是算法学习的时候,有个不错的IDE可以帮你跟踪代码的运行过程,还能比较容易的做性能分析,这样就可以用动态、直观、形象的视角去理解和观察算法。这对学习非常有帮助。
如果只是在一个特定的领域做知识学习的工具,其实C++反而不算很难,C++的难度主要在于覆盖的领域太广泛,当你要做一个专业的C++程序员,要掌握的东西就太多了。
个人不太建议用C去学习这些东西,需要处理太多跟问题本身无关的事情了。 科研类 matlab 这几个语言的算法我都略有涉及, 勉强有资格回答这个问题.
算法本身是很理想的产物, 但是不得不持续的跟语言去平衡.
类似物理是数学和现实的折衷.
算法也是数学和语言的折衷.
其实算法对于一般工程师的要求其实很低, 本质上就是一个表:
| 算法名 | 算法复杂度 | 算法可能的使用场景 |
所以对于工程师而言, 能够认识到算法的细节已经算超标要求了.
意识到这些语言的细节将会是工程师基本素养的一部分. 以至于常年固定在一门语言的工程师会分辨不出来这些到底是语言的细节, 还是算法的细节.
## 对于工程师而言:
一般认为使用C++/Java算是基本平衡算法和语言细节的.
(但是请问你写那么多public和private能体会多少算法背后的力量呢?)
比如你用了一个需要用到指针做索引, 但这种类型的`编程语言`却无法使用指针, 那么你就不得不多设计一个数据结构来巧妙的规避这些.
我曾经仔细的思考过不同类型语言对**算法**和对**实现算法**的影响.
在实现算法的时候有很多算法相关的细节并不可规避, (而且也不应该去规避) 但是如果语言的细节干扰程度过多, 就会迷失在语言的黑洞里. 本来就分不清到底是应该是哪个是哪个.
如果对着>这本书去写, 那么推荐你就用java写. 因为可以直接绕过语言的坑.
如果是>, 那么其实语言本身不是问题, 本书其实基本是pseudo-code, 而且针对不同语言的讲解了很多语言的细节.
我曾经用C++实现过本书绝大多数的算法, 也用python实现过本书里面的部分算法. 相比之下, C++会比较正统. python则语言细节略多.
但是由于一直以来java程序员的数量, 往往会造成一种Java-like的语言才更适合写算法. 其实这点本应该引起工程师们的警惕.
## 对于体会算法背后的细节(数学, 思想)而言:
我认为尽可能的少触碰语言细节去体会算法细节是最重要的.
上面有推荐Matlab的, 事实上Matlab会使得你离开计算机系去数学系.
所以一般认为Matlab 更适合其他行业的人员参与.
1. Matlab涉及语言细节比较少, (大部分Matlab的使用者很少关心语言细节.)
2. Matlab观察原理很方便,
3. 方便进一步的图形化,
4. Matlab本身在学习算法之后也可以作为补充工具.
matlab 真是一个古老而博大精深的语言, 其实现在而言[Julia](The Julia Language)类似Matlab, 在我看来, 其实会避免更多语言的细节.
对于楼主而言也算很不错的一个选择.
我认为楼主可以考虑一下Matlab, (当然还有Julia)
> 纸上得来终觉浅,绝知此事要躬行
最后:
我几乎没写过C#的算法, 在此不表. 不过无论选那种语言, 要完整的自己写出来才能真正领悟. 建议C++ 或者Python。 Python 的话,写起来更方便一些, 但是生产中考虑性能的话,更多的还是用C++ 实现 Go没有接触过,用C++,Python和 Matlab写过一些算法,感觉就算法本身来说,区别并不大,你希望关注算法的思想和原理那就多注意算法的整体性~~有数学和物理背景的话应该不是什么难事,一直认为本科阶段读一个数学相关专业再来念研究生比较好(仅仅是个人看法,就计算机专业来讲的) 必须是matlab。
其实是python和Fortran。
c/c++这个坑 如不是必须,尽量别入坑
============
反对说传统语言对于非计算机或者非信息类专业的学生 适用C/C++/Java实现算法的说法。
我自己把算法分为两种,狭义算法 和 广义算法。
狭义算法 指 算法导论 数据结构 离散数学 操作系统 等课程中 涉及的算法,这类算法不用高等数学、微积分、微分方程、数理统计等知识。
此类算法一般是计算机系大学生所说的算法。
广义算法 就比较宽泛了,任何数学公式,都可以成为算法,此类算法在数学系、信息系同学的专业课中非常常见,比如DSP算法,这种涉及到离散傅里叶变换的 算法,你能说这些跟数据结构里面的类似快速排序的算法 你觉得是一回事情么?
对于物理系、信息系的同学来说,他们只是需要一个超级计算器,他们不是研究编程,是一个研究背景下,我要优化 改进一个算法 我要快速研究一个算法是否可行。他们始终是在研究数学,而非研究如何更好的编程当一个优秀而杰出的码农。
而matlab正式这样一种学习成本低,对于实现广义算法非常友好的超级计算器,生产效率是非常高的,另外也带有IDE和调试工具,Debug也不差的,另外还有simulink等非常厉害的工具。
所以首推matlab。
另外对于学有余力的同学,掌握C++ / Java 或者结合相关背景选择 一门普通编程语言(如机器学习的同学,去学习Python)都是非常好的。
当然如果你已经是资深C++/Java语言的user,那么你自然不必回头再去学matlab 单纯学算法,Matlab最好。结合Matlab的可视化工具,算法过程可以更容易理解。而且基础学科专业,在Matlab上反正是要投资的,不如现在就开始。
不同意使用C/C++学习算法,尤其是楼主并不是计算机专业的情况下。用C写算法涉及到太多编程技巧和与算法无关的事项,光是内存管理这一块就很麻烦,更别提无法绕开的各种指针操作。如果在C++上实现算法,比起C来优势也就是多个泛型。没有泛型,算法不能通用,但是楼主的目的是学习算法,不是去实现工业级质量的通用算法(stl早就实现了)。那么泛型就是个徒增学习曲线的概念,没必要去动它,就只拿float32做算法实现了又怎么样? 按我的概念,C、C++是用来写算法的,matlab、python这些是用来用算法的。
目前学编程的主要目的不是为了做项目或者找工作或者写paper,而是打算用《算法导论》这书学算法的时候写程序实现一下,或者对一些感兴趣的事情建模分析。对于算法,我比较在意的不是具体实现的细节,而是背后的思想和数学原理。
我听说C/C++在写算法的时候,会花大量时间来处理和实现相关的细节上,而Java和python写算法能比较集中到算法本身的内涵上。请问的确有这种情况吗?
如果python或者Go比较适合写算法,请问下像我这样背景的人适合用什么样的书或者资料上手这些语言?
如果C/C++写算法比另外几种语言要更合适,那C和C++在这方面具体的区别是什么?我有需要再额外学习C++,还是继续深入锻炼C语言的能力?
第一次在知乎上提问,感谢!
回复内容:
目前学编程的主要目的不是为了做项目或者找工作或者写paper,而是打算用《算法导论》这书学算法的时候写程序实现一下,或者对一些感兴趣的事情建模分析。对于算法,我比较在意的不是具体实现的细节,而是背后的思想和数学原理。你的要求本身是矛盾的
学《算法导论》的核心目标之一是建立起对算法复杂度的全面理解和感受,这当然要在一个容易对性能建模/预测的系统上实验比较好,比如C/C++这些runtime基本不做什么额外操作的“纯被动”的高度可预测的系统。你选择一个有managed Memory/IO的系统,结果字面上的O(1)操作其实背后有时不是O(1)的,那你不等于自寻困扰么
你想对感兴趣的事情建模分析,这是数学或是其他学科的范畴。这时当然用高级的工具比较好。别的不说,单单做个整数数值计算还要考虑数值太大了会不会溢出这些机器层次上的问题不是浪费时间么
【我听说C/C++在写算法的时候,会花大量时间来处理和实现相关的细节上,而Java和python写算法能比较集中到算法本身的内涵上。请问的确有这种情况吗?】
不对。你用C++也可以不处理实现相关的细节,没人逼你这么做。
数据结构和算法从本质上来讲就是泛型的。你要么使用C++的模板,要么用python的动态类型。C和go都会让你觉得搞起来很苦逼。不过目前调试C++的IDE都比python要强太多,如果你本来就会C++,那就用C++。
仅仅就学习算法,还是C++/Java/C#最适合。首先,没泛型的语言未必工作不好用,我司现在服务端代码几乎都是go,但是没有泛型,写通用的代码就是不好用。我用Go把半本《算法》实现了一遍,移植了Haskell 的 Parsec 库。这些代码大部分都在我团队的项目里实际使用。你要说 Go 有多熟练未必,但是要说它在语言功能上有多少坑我倒是挺熟悉。没泛型的话算法实现起来太坑人了,别的不说 float32/float64/int8/int16/int32/int64/int 这些数值类型你能都覆盖么?如果只是基于某一组有限的数据类型和问题领域实现一遍,用 go 倒是不错,它环境配置容易,不太依赖ide,但是对ide还是比较友好的,天然集成test,编译快速,模型简单,学习容易,可以说是我用过的静态编译型语言里最像动态脚本语言,最适合快速开发微型工具的。
其次,Python/Ruby 这类语言其实不太适合练习算法实现,它们太“高级”了。例如用Python的时候,你很难规避它的内置容器List和Dict,这些东西封装了太多东西,在学习的过程中容易被干扰。另外没有静态的类型控制,在学习过程中也会失去一些知识。倒不是就会导致你后半生这部分都不能自理,但是需要另外学习。
在我的经验,要学习算法,C++/C#/Java 仍然是比较好的选择,它们的泛型已经比较成熟,能够在学习中建立比较完备的知识概念。可以找到一些比较好的IDE用,我个人其实在工作中不怎么用IDE,但是算法学习的时候,有个不错的IDE可以帮你跟踪代码的运行过程,还能比较容易的做性能分析,这样就可以用动态、直观、形象的视角去理解和观察算法。这对学习非常有帮助。
如果只是在一个特定的领域做知识学习的工具,其实C++反而不算很难,C++的难度主要在于覆盖的领域太广泛,当你要做一个专业的C++程序员,要掌握的东西就太多了。
个人不太建议用C去学习这些东西,需要处理太多跟问题本身无关的事情了。 科研类 matlab 这几个语言的算法我都略有涉及, 勉强有资格回答这个问题.
算法本身是很理想的产物, 但是不得不持续的跟语言去平衡.
类似物理是数学和现实的折衷.
算法也是数学和语言的折衷.
其实算法对于一般工程师的要求其实很低, 本质上就是一个表:
| 算法名 | 算法复杂度 | 算法可能的使用场景 |
所以对于工程师而言, 能够认识到算法的细节已经算超标要求了.
意识到这些语言的细节将会是工程师基本素养的一部分. 以至于常年固定在一门语言的工程师会分辨不出来这些到底是语言的细节, 还是算法的细节.
## 对于工程师而言:
一般认为使用C++/Java算是基本平衡算法和语言细节的.
(但是请问你写那么多public和private能体会多少算法背后的力量呢?)
比如你用了一个需要用到指针做索引, 但这种类型的`编程语言`却无法使用指针, 那么你就不得不多设计一个数据结构来巧妙的规避这些.
我曾经仔细的思考过不同类型语言对**算法**和对**实现算法**的影响.
在实现算法的时候有很多算法相关的细节并不可规避, (而且也不应该去规避) 但是如果语言的细节干扰程度过多, 就会迷失在语言的黑洞里. 本来就分不清到底是应该是哪个是哪个.
如果对着>这本书去写, 那么推荐你就用java写. 因为可以直接绕过语言的坑.
如果是>, 那么其实语言本身不是问题, 本书其实基本是pseudo-code, 而且针对不同语言的讲解了很多语言的细节.
我曾经用C++实现过本书绝大多数的算法, 也用python实现过本书里面的部分算法. 相比之下, C++会比较正统. python则语言细节略多.
但是由于一直以来java程序员的数量, 往往会造成一种Java-like的语言才更适合写算法. 其实这点本应该引起工程师们的警惕.
## 对于体会算法背后的细节(数学, 思想)而言:
我认为尽可能的少触碰语言细节去体会算法细节是最重要的.
上面有推荐Matlab的, 事实上Matlab会使得你离开计算机系去数学系.
所以一般认为Matlab 更适合其他行业的人员参与.
1. Matlab涉及语言细节比较少, (大部分Matlab的使用者很少关心语言细节.)
2. Matlab观察原理很方便,
3. 方便进一步的图形化,
4. Matlab本身在学习算法之后也可以作为补充工具.
matlab 真是一个古老而博大精深的语言, 其实现在而言[Julia](The Julia Language)类似Matlab, 在我看来, 其实会避免更多语言的细节.
对于楼主而言也算很不错的一个选择.
我认为楼主可以考虑一下Matlab, (当然还有Julia)
> 纸上得来终觉浅,绝知此事要躬行
最后:
我几乎没写过C#的算法, 在此不表. 不过无论选那种语言, 要完整的自己写出来才能真正领悟. 建议C++ 或者Python。 Python 的话,写起来更方便一些, 但是生产中考虑性能的话,更多的还是用C++ 实现 Go没有接触过,用C++,Python和 Matlab写过一些算法,感觉就算法本身来说,区别并不大,你希望关注算法的思想和原理那就多注意算法的整体性~~有数学和物理背景的话应该不是什么难事,一直认为本科阶段读一个数学相关专业再来念研究生比较好(仅仅是个人看法,就计算机专业来讲的) 必须是matlab。
其实是python和Fortran。
c/c++这个坑 如不是必须,尽量别入坑
============
反对说传统语言对于非计算机或者非信息类专业的学生 适用C/C++/Java实现算法的说法。
我自己把算法分为两种,狭义算法 和 广义算法。
狭义算法 指 算法导论 数据结构 离散数学 操作系统 等课程中 涉及的算法,这类算法不用高等数学、微积分、微分方程、数理统计等知识。
此类算法一般是计算机系大学生所说的算法。
广义算法 就比较宽泛了,任何数学公式,都可以成为算法,此类算法在数学系、信息系同学的专业课中非常常见,比如DSP算法,这种涉及到离散傅里叶变换的 算法,你能说这些跟数据结构里面的类似快速排序的算法 你觉得是一回事情么?
对于物理系、信息系的同学来说,他们只是需要一个超级计算器,他们不是研究编程,是一个研究背景下,我要优化 改进一个算法 我要快速研究一个算法是否可行。他们始终是在研究数学,而非研究如何更好的编程当一个优秀而杰出的码农。
而matlab正式这样一种学习成本低,对于实现广义算法非常友好的超级计算器,生产效率是非常高的,另外也带有IDE和调试工具,Debug也不差的,另外还有simulink等非常厉害的工具。
所以首推matlab。
另外对于学有余力的同学,掌握C++ / Java 或者结合相关背景选择 一门普通编程语言(如机器学习的同学,去学习Python)都是非常好的。
当然如果你已经是资深C++/Java语言的user,那么你自然不必回头再去学matlab 单纯学算法,Matlab最好。结合Matlab的可视化工具,算法过程可以更容易理解。而且基础学科专业,在Matlab上反正是要投资的,不如现在就开始。
不同意使用C/C++学习算法,尤其是楼主并不是计算机专业的情况下。用C写算法涉及到太多编程技巧和与算法无关的事项,光是内存管理这一块就很麻烦,更别提无法绕开的各种指针操作。如果在C++上实现算法,比起C来优势也就是多个泛型。没有泛型,算法不能通用,但是楼主的目的是学习算法,不是去实现工业级质量的通用算法(stl早就实现了)。那么泛型就是个徒增学习曲线的概念,没必要去动它,就只拿float32做算法实现了又怎么样? 按我的概念,C、C++是用来写算法的,matlab、python这些是用来用算法的。
上一篇: PHP的curl造成性能瓶颈,怎么优化
下一篇: java操作系统剪贴板内容数据