browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

不要为了使用递归而使用递归

Posted by on 2008 年 03 月 26 日

你可以任意转载本文,但请在转载后的文章中注明作者和原始链接。
媒体约稿请联系 titilima_AT_163.com(把“_AT_”换成“@”)。

关于递归,《代码大全》(第2版)的P397~398如是写道:
在计算机科学教科书中存在着这样的缺陷,那就是用愚蠢的例子来讲解递归。典型的例子就是计算阶乘或者斐波纳契数列。递归是一种强有力的工具,但是把它用在这两者中的任何一种都是愚蠢之极的。如果为我工作的程序员用递归去计算阶乘,那么我宁愿换人。
接下来,对于这个问题的理由,作者解释道:
除了速度缓慢,并且无法预测运行期间的内存使用状况以外,用递归写出的子程序要比用循环写出的子程序更难理解。
最后,作者为之总结了三点经验:

  • 首先,计算机科学教程中给出的递归示例没有给这个世界带来任何的好处。
  • 其次,也是更为重要的,递归是一种非常强大的工具,其功能之强大要远远超出使用它们来稀里糊涂地计算阶乘或者斐波纳契数列。
  • 再次,也是最重要的,在用递归之前你应该考虑它的替换方案。

之所以援引《代码大全》原书这么多的内容,是由于国内的确有很多的学究课本使用了阶乘或斐波纳契数列来讲解递归。也许砖家和叫兽们找不到更合适的示例,又也许是他们的程序永远运行在超高速CPU和无限内存的机器上——这一切,我是无从得知的。我唯一了解的情况是:我们现实中所使用的机器并不能给我们提供一个理论上完美的运行环境——亦即是说,在某些严苛的条件下,你用来计算阶乘或斐波纳契数列的代码将有可能收到一个系统崩溃。
掌掴学究欢迎提供各类素材,请致信titilima@163.com

订阅本站

6 Comments

  • At 2008.03.26 19:43, free2000fly said:

    是的, 可能会造成栈空间耗尽, 所以啦, 建议用 stl 的 stack 替换之, 好使的很, 就是稍微复杂点.

    • At 2008.03.29 14:46, sinper said:

      大数据量的情况下,一般用数组进行模拟运算的…

      • At 2008.06.14 13:39, baihi said:

        都是真不明白还是装不明白啊。
        教材的例子用于说明,特别是程序含义的表达,那两个例子确实不够好,给对一知半解的初学者对,递归的进一步理解造成了困扰。但它足够简单,让你知道了递归的基本概念,从起步教材的角度上看,已经完成了任务,只是不漂亮罢了。
        因为它不是算法导论一类的专注,别国外说点什么都跟风。

        • At 2008.06.16 09:13, 李马 said:

          [quote=baihi]都是真不明白还是装不明白啊。
          教材的例子用于说明,特别是程序含义的表达,那两个例子确实不够好,给对一知半解的初学者对,递归的进一步理解造成了困扰。但它足够简单,让你知道了递归的基本概念,从起步教材的角度上看,已经完成了任务,只是不漂亮罢了。
          因为它不是算法导论一类的专注,别国外说点什么都跟风。[/quote]
          我想这个例子会更好一些:有兄弟五个,我问老大多大岁数,老大说:我比老二大1岁。
          问老二,答:我比老三大1岁。
          再问老三,答:我比老四大1岁。
          又问老四,答:我比老五大1岁。
          最后问老五,答:我6岁。
          不过还是感谢您的意见。

          • At 2008.11.07 18:02, bzero1982 said:

            说实在的 我讨厌递归

            • At 2009.02.22 18:22, releaseman said:

              所有的递归皆可有循环实现.

              (Required)
              (Required, will not be published)