持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情
递归和全局变量
您可能听说过递归,并且很可能将其视为一种相当微妙的编程技术。这是计算机科学家传播的一个迷人的都市传说,让人们认为我们比实际情况更聪明。递归是一个重要的想法,但它并不那么微妙,它不仅仅是一种编程技术。作为一种描述性方法,递归被广泛使用,即使是那些从未梦想过编写程序的人也是如此。考虑美国法典的一部分,定义“与生俱来的权利”公民身份的概念。粗略地说,定义如下
·任何在美国境内出生的孩子,或
任何在美国境外婚生子女,其父母一方为美国公民。
第一部分很简单;如果你出生在美国,你就是一个与生俱来的公民(如巴拉克·奥巴马)。如果您不是在美国出生,这取决于您的父母在您出生时是否是美国公民。你的父母是否是美国公民可能取决于他们的父母是否是美国公民,等等。
通常,递归定义由两部分组成。至少有一个基本情况直接指定特殊情况的结果(上面示例中的情况 1),并且至少有一个递归(归纳)情况(上面示例中的情况 2)根据其他输入的问题的答案来定义答案,通常是同一问题的更简单版本。正是基本情况的存在使递归定义不再是循环定义。
世界上最简单的递归定义可能是自然数上的阶乘函数(通常在数学中用!)。
第一个等式定义了基本情况。第二个方程定义了所有自然数的阶乘,除了基数,根据前一个数的阶乘。
图 6-1 包含阶乘的迭代 (fact_iter) 和递归 (fact_rec) 实现。
此函数非常简单,这两种实现都不难遵循。不过,第二个是原始递归定义的更直接的翻译。
通过从fact_rec体内调用fact_rec来实现fact_rec几乎就像作弊一样。它的工作原理与迭代实现的工作原理相同。我们知道迭代实际上迭代将终止,因为n从正开始,并且每次循环周围都会减少1。这意味着它不能永远大于 1。同样,如果使用 1 调用fact_ rec,则返回一个值而不进行递归调用。当它进行递归调用时,它始终使用小于调用它的值。最终,递归以调用fact_rec(1) 终止。