为什么编程竞赛参赛者使用C ++和Java?
在参加今年的Google Code Jam比赛之后,我不禁注意到使用C / C ++和Java的[成功的]参赛者令人难以置信。 在整个比赛中使用的语言的分布可以在这里看到。
在C / C ++编程几年之后,我最近爱上Python,因为它的可读性/直接性。 最近,我学习了像OCaml,Scheme这样的函数式语言,甚至像Prolog这样的逻辑语言。 这些语言当然有其优点,在我看来,在某些情况下,比C ++和Java更容易应用。 例如,Scheme使用call / cc简化了回溯(一种回答几个问题所需的工具),而Prolog的逻辑规范虽然由于其强大的性质而效率低下,但能够大大简化(甚至自动解决)某些难以解决的问题把自己的大脑包裹起来。
很明显,竞赛参赛者应该使用最适合挑战的工具。 即使是x86组装也是图灵完整 – 这并不能解决问题。 在这种情况下, 使用C / C ++和Java的参赛选手为什么使用像Scheme / Lisp,Prolog甚至Python这样的不常用语言的参赛者显然不那么成功? 换句话说, 为什么不成功的参赛选手使用的语言虽然可能不太主stream,却可以说是更好的工具?
我的问题有几个动机。 最重要的是,我想成为一个更好的程序员 – 无论是在实践方面还是在竞争方面。 在被引入function和逻辑编程这样美丽的范例之后,看到有那么多人抛弃它们,转而支持C / C ++和Java,让人感到沮丧。 它甚至让我质疑我对所说范例的钦佩,担心在编程竞赛中我不能成为Lisp / Scheme / Prolog程序员。
好问题! 作为一个参与编程竞赛的人,我可能有话要说。
[让我们从标准免责声明中获益:比赛编程只与“现实世界中的编程”松散地相关,并且在testingalgorithm和解决问题的技巧以及能够提出快速无错的工作代码时间压力,它不一定与build立大型软件项目,编写可维护的代码等相关(除了结构良好的程序更容易debugging)。
现在有一些答案:
-
在现实世界中,C ++ / Java比其他语言更为常见,所以您希望在任何地方都能看到更高的比例。 (但比赛人数更高)
-
这些参与者中有许多是学生,或是作为学生参加竞赛,而C ++ / Java是学生学习的更常见的“第一语言”。 (现在的大学生可能会以Scheme,Haskell,Python等等开始,但是高学生(通常是自学的)较less。)事实上,许多东欧的参与者仍然使用Pascal,而且更加令人吃惊比我们其他人会用任何语言。
-
学校和大学级比赛通常使用这些语言。 国际信息学奥林匹克(IOI)只允许C,C ++和Pascal(或者现在允许Java;我没有跟上),ACM ICPC只允许C,C ++和Java。 TopCoder允许C ++,Java,C#和VB(真的:P); 和最近,Python。 所以你可以说“比赛生态系统”里面有更多的C ++ / Java程序员。 实际上,Google Code Jam和IPSC是less数允许使用任何语言编码的竞赛。
-
现在的问题是,在GCJ中参赛者可以自由select一种语言,他们为什么不selectPython或Scheme? 最相关的因素是这些语言很慢 。 当然,对于大多数真实世界的编程来说,它们很容易就足够快了,但是对于所有testing用例在n秒限制下运行的程序来说,这些语言通常都会涉及到严格的循环。在algorithm上涉及更多的问题。 (一个devise接受O(n log n)解决scheme的问题,而不是C / C ++的Θ(n 2 )解决scheme通常排除了在较慢语言中的最优O(n log n)解决scheme。 USACO;我不确定情况如何。)
-
另一个因素是库:C ++和Java有更好的常用algorithm和数据结构库(例如红黑树,C ++的next_permutation),而Python的库(对于真实世界来说足够好用)在这里用处不大,Prolog和Scheme …我不知道他们的图书馆。 这是一个相对较小的因素,因为这些程序员可以在必要时编写自己的代码。 🙂
-
通用的多范式语言比在竞赛的时间限制内完成任务更有用,而不是强迫你做哲学或者做事的语言。 例如,这就是为什么Prolog总是不受欢迎的原因。 (一般哲学:有些语言是“启用”的语言,可以让你做任何事情,包括在脚下开枪,有些是“指挥”,迫使你做正确的事情)。这也是为什么C ++比三倍stream行爪哇在一般的比赛参与者,更受欢迎的最佳参赛者之一。 因为代码不需要被其他人阅读,所以可以使用
FOR(i,n)
这样的循环macros(input较less的代码,更重要的是在匆忙中产生错误的可能性较小)。 没有任何反对Java的,也有一些使用Java的顶级程序员。 🙂 -
最后,虽然这些顶级程序员中有许多可能拥有C ++ / Java / Pascal作为他们的“第一语言”,但由于他们的语言,他们并不好,所以您不必对此失望。 许多同样的程序员甚至有意使用疯狂的语言,比如shell脚本,m4(用在autoconf中)和程序集(名为“你不能用ASM拼写真棒”的团队),赢得了比赛。
我喜欢Jerry Coffin关于绘制Google AI比赛参赛者的想法,所以我把所有的结果绘制出来(计算出的平均值,标准偏差,然后绘制出Excel中的正态分布曲线)。
与Lua和JS,得到这个:
没有(参赛者很less,所以结果可能偏斜):
看起来Java的参与者明显比其他人差,而Go,Common Lisp和C则更好。
为什么我们都说英语而不是世界语 ? 那么,就这样发生了。 尽pipe英语不一致和臃肿,世界语故意被devise为“更好的工具”。
因此,一个原因是一个传统。 在大多math校,编程仍然以C / C ++,Java,Pascal甚至Basic教授。 参加那些比赛的学生大多select他们认识的语言。
另外,您可以注意到,大多数algorithm书籍都采用Pascal或Ada风格的psedudocode,而Lisp则很less。 我不知道为什么,也许也是一个传统。 或者对于algorithm来说可能不太好。
另一个原因是速度。 虽然这对Google Code Jam来说不是问题,但在几乎所有的比赛中,“接受”和“时间限制”判决之间的差距是两倍。
换句话说,如果C ++中的最优化algorithm运行速度比Ruby快10倍,那么可能意味着C ++中的次优化algorithm仍然比Ruby中的优化algorithm快。 如果O(n * logn)可以实现,竞赛作者通常不希望允许O(n ^ 2)提交。
首先,我会质疑你的前提[编辑:或者我认为是一个前提 – 那些使用C ++和Java的参赛者也同样好]。 例如,以下是Google最近的AI比赛前100名和最后 100个名额使用的语言:
使用C ++和Java的参赛者在比赛中似乎没有任何接近同样成功的地方。 使用Python的参赛选手似乎也不是特别好,尽pipe其中的数量相当less,这削弱了这方面的任何结论。
其次,当然,很多解释(正如其他人所指出的)无疑只是熟悉每种语言的人数。 现在可能有更多的人参加Java课程,而不是任何Lisp,Scheme或Prolog的总人数。
编辑:我认为第三种可能性只是多function性。 举一个极端的例子,Prolog非常适合于一些问题,但同样适用于其他许多问题。 很less有人能够(或者至less是)学习超过一种或两种语言,足以在竞赛中使用它们,所以大多数对此类事物感兴趣的人可能会select几乎适合任何事情的语言,而不是试图为每一个可能select的问题学习一门专门的语言。
在几乎所有Google Code Jam轮次中,更多高性能的参赛者以C ++编码。
以下是Google Code Jam 2012 Round 1A,1B和1C(从上至下排列)的语言统计数据。 每轮参赛人数分别为3,686,3,281和3,189人。
有趣的问题,可能应该是社区维基。
查看各国的入围人数: http : //www.go-hero.net/jam/10/regions 。 注意到东欧和俄罗斯的人数。 这些地方有很多强大的C ++社区,还有Java,原因很多。
在限定词中查看数字语言: http : //www.go-hero.net/jam/10/languages/0和决赛: http : //www.go-hero.net/jam/10/languages/6 。 C ++的起点不到一半,总决赛有75%。 好的程序员更喜欢使用C ++或C ++来编写程序员。 当你掌握C ++的时候,其他的事情可能变得微不足道了。
你可以自由地得出你自己的结论。
首先,正如你所指出的, C++
和Java
是主stream语言。 这些自动意味着开始进行编程竞赛的人将会首先被介绍给他们 – 通过学习Lisp
作为第一语言的方式:)我也经常参与这样的竞赛 – 尽pipe我最喜欢的语言是Java
,但是我使用C++
来进行竞争。 这只是我想练习除Java
之外的另一种语言 – C++
也稍微冗长,运行速度更快,这对于编程竞赛非常重要。 现在我认为 – 人们成为主stream语言的第一人。 要参加编程比赛,您必须掌握您所使用的语言。 你没有时间在互联网上search愚蠢的东西 – 就像忘了一个构造。 这只是速度是一个重要的因素。 在比赛中使用Lisp
,你一定喜欢它。 我不认为那里有这么多人。 纠正我,如果我错了。 诚实地说,你提到的专业人士就像简化回溯:无论什么语言,回溯都很容易 – 申报一个方法,只是再次调用它的每一个可能的结果。 这不可能更简单。 直到现在我还没有感觉到,我正在使用的语言是试图跳出编程比赛的脚步。
OMG …人们都在经历统计数字!
让我们不要忘记基础知识..这些是唯一的两种语言(主要是)在大学/学校教给人们…!
这可能会回应沉重的冲击!
一个重要的原因可能是每个比赛都不支持python或prolog等语言。 特别是ACM ICPC世界总决赛支持C / C ++和Java 。 TopCoder也只支持C ++,Java,C#,VB和Python 。 参赛者自然会select一种在每场比赛中可用的语言。 另一个原因可能是执行速度。 是的,另一个原因是这些是大多数人首先学习的语言。
在ACM ICPC中,大型图书馆是Java的卖点。 能够实现你想要的一些随机的数据结构或algorithm,只是把它拉出标准库是很方便的。
请记住,C ++不仅是所有参赛选手中的大多数,而且随着轮次的进步,其比例也在不断提高。
我想说的是,大部分参与者都是学生(不过,由于这是一个公开的比赛,有机会接受谷歌的面试,所以你必须考虑到很多参与者都是gradle的)。 但最新的一轮只是对经验丰富的人而言。 他们不仅仅是学习用C ++ / Java编程的学生。
当然,学生的观点也适用于LISP和OcaML或ProLog等语言。 那就是在AI领域使用很多的语言,但在主stream世界里,学生最有可能学习和使用它们。
除了谷歌支持几种语言以外的大型竞赛,但是这仍然不能解释为什么Pascal或.net不接近Java级别(因为他们倾向于在主要竞赛活动中得到同样的支持)。
很多这些比赛中最好的编码者都知道很多语言。 但他们仍然喜欢在使用C ++的过程中,首先比“学习C ++”更重要。
我认为,除了C ++或Java之外的其他语言是更好的工具。 如果直接数据说入围者更有可能使用C ++和Java,那么这个说法是直接的矛盾。
Google AI竞赛数据实际上并不矛盾任何关于代码堵塞的前提。 实际上,它确实表明,顶级编码人员能够使用像Common Lisp这样的语言,因为它确实是更好的工具。 如果我们想用这些数据来假设CLISP是AI竞赛的一个很好的工具,那么我们也应该假设C ++对于像GCJ这样的algorithm竞赛来说是一个很好的工具。