读《代码大全2》,已经读了一半,喘口气。总结八个字:百科全书,受益匪浅。小到一个赋值语句、一个循环的编写,大到需求分析、架构设计,无所不包,看后
半部分目录,更是扯到了重构、软件工艺、程序员的性格特征这样的话题。恰好手边的工作暂时比较有闲,可以实践下“创建高质量的代码”中的部分建议,晚上读
书,第二天就重构,乐在其中。这一部分中对设计、子程序、类、变量、语句的处理建议,可能你平常已经在这么做,可作者这么精辟地概括出来让人叹服,而有些
地方是你平常绝对很少注意的,特别是在变量和三种常见控制语句的处理上。
说说我认为是缺点的地方,就是作者貌似对函数式语言了解很少,举的例子全部用的是广泛应用的静态语言(c/c++,java,vb)。例如作者有这么一句话:如果为我工作的程序员用递归去计算阶乘,那么我宁愿换人。作者对递归的态度相当谨慎,这在静态命令式语言中显然是正确的,但是在函数式语言中,由于有尾递归优化的存在,递归反而是最自然的形式,况且我打心里认为递归更符合人类思维。请注意,在FP中只有尾递归的程序才是线性迭代的,否则写出来的递归可能是线性递归或者树形递归,两种情况下都可能导致堆栈溢出并且性能较差。
scheme写阶乘:
(define (fac n)
(if (= 1 n)
1
(* n (fac (- n 1)))))
显然这个版本不是尾递归,计算过程是一个线性递归过程,计算(fac 4)的过程如下:
(* 4 (fac 3))
(* 4 (3 * (fac 2)))
(* 4 (3 * (* 2 (fac 1))))
(* 4 (3 * (* 2 1)))
(* 4 (3 * 2))
(* 4 6)
24
因为解释器是采用应用序求值,需要将表达式完全展开,然后依次求值,在这个过程中,解释器内部需要保存一条长长的推迟计算的轨迹。
改写成一个尾递归版本:
(define (fac n)
(define (fac-iter product n)
(if (= 1 n)
product
(fac-iter (* n product) (- n 1))))
(fac-iter 1 n))
我们来看看它的计算过程:
(fac-iter 1 4)
(fac-iter 4 3)
(fac-iter 12 2)
(fac-iter 24 1)
24
可以看到,在这个过程中,解释器不需要保存计算轨迹,迭代的中间结果通过product变量来保存,这是一个线性迭代的计算过程。
最后再看一个斐波拉契数列的例子:
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else
(+ (fib (- n 1)) (fib (- n 2))))))
这个计算过程展开是一个树形递归的过程(为什么说是树形?展开下计算过程就知道),改写为线性迭代:
(define (fib n)
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
(fib-iter 1 0 n))
上述的内容在sicp第一章里有更详细和深入的讨论。
分享到:
相关推荐
java中使用递归方法计算阶乘的代码示例
在Java中,我们可以创建一个名为`factorial`的方法,该方法接受一个整数n作为参数,然后通过递归调用来计算阶乘。以下是具体实现: ```java public class Factorial { public static void main(String[] args) { ...
python非递归方式计算阶乘(循环)
这个函数会接受一个整数作为参数,然后根据递归定义计算阶乘。递归的基本思想是将大问题分解为小问题,直到小问题简单到可以直接求解。在阶乘的例子中,我们利用0的阶乘是1(0! = 1)这一基础,以及n的阶乘等于n乘以...
总结一下,VB递归求阶乘的关键在于定义一个自调用的函数,通过不断缩小问题规模,最终达到基本结束条件。这个过程中,递归函数的结束条件、递归调用以及返回值的计算是三个核心要素。通过学习和实践这个例子,你可以...
本文将深入探讨递归求和与计算阶乘这两个主题。 首先,我们来看递归求和。递归求和是通过递归子程序实现的,它通常包含一个终止条件以避免无限循环。以`CalcSum`为例,这个过程接受一个整数`n`作为输入参数,并计算...
在VB6.0中,我们可以创建一个函数来实现递归计算阶乘。下面我们将详细介绍如何编写这个函数: 首先,我们需要创建一个新的标准模块,在该模块中定义一个名为`Factorial`的函数。函数的参数为一个正整数n,返回值...
在这个场景中,我们讨论的是使用易语言实现的递归算法来计算阶乘。 阶乘是一个数学概念,表示一个正整数n的所有小于等于n的正整数的乘积,通常表示为n!。例如,5!(5的阶乘)等于5×4×3×2×1=120。递归算法求阶乘...
- `main()` 函数是程序的入口点,负责接收用户输入并调用 `jc()` 函数来计算阶乘。 - `jc()` 函数实现了递归求阶乘的功能。 2. **主函数 main()**: - 首先定义了四个整型变量 `n`, `j`, `i` 和一个整型数组 `...
python递归方式计算阶乘
**非递归方法**:也可以使用循环结构(如for循环)来计算阶乘,这种方式不会导致栈溢出,但可能不如递归直观。 #### 递归与迭代的对比 - **递归**:通常代码更简洁、逻辑更清晰;但可能效率较低,且可能导致栈溢出...
在这个主题中,我们将深入探讨如何使用递归算法在VB6.0(Visual Basic 6.0)中计算阶乘。VB6.0是Microsoft开发的一款经典可视化编程环境,用于创建Windows应用程序。 阶乘是一个数学概念,表示一个正整数n的所有...
(3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低,所以一般不提倡用递归算法设计程序。 (4)在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储,递归次数过多容易造成栈溢出等。
C语言练习程序,采用递归方法求阶乘.调用子函数实现
【基础算法】-python递归求阶乘和阶乘:是指从1到n的连续自然数相乘的积。负数没有阶乘。递归:函数作为一种代码封装,除了被其他程序正常调用外...# 本程序:根据用户输入的整数n,计算并输出n的阶乘和# 递归实现阶乘
在编程领域,阶乘是一个非常基础且...总的来说,Java利用递归计算阶乘是一种直观而简洁的方法,但它同时也涉及到递归函数的基本原理和递归深度限制的问题。理解这些知识点对于深入学习Java和计算机科学是非常有帮助的。
C#递归计算求阶乘和求年龄实例源码 1、n!=n*(n-1)*(n-2)*......*3*2*1 n!=n*(n-1)! 2、 趣味问题——年龄。有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个...
递归算法为计算阶乘提供了一种简洁而直观的方法。 递归算法的基本思路是将大问题分解为小问题,直至问题变得足够简单可以直接求解。在求阶乘的过程中,我们可以设定以下两个基本条件: 1. **基本情况**:0的阶乘...
在这个场景中,我们关注的是递归算法在计算阶乘中的应用。阶乘是一个数学运算,表示所有从1到指定整数n的所有正整数的乘积,通常表示为n!。例如,5的阶乘(5!)等于5 * 4 * 3 * 2 * 1。 在Java程序中,有两种常见的...
文档中涵盖了递归阶乘的基本概念,包括如何使用递归计算阶乘以及如何在Java中实现递归阶乘。此外,文档还包括一个逐步指南,介绍如何在Java中实现递归阶乘的代码,包括详细的代码示例和实现细节。 文档还涵盖了高级...