六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 49|回复: 0

递归(Recursion)

[复制链接]

升级  92%

12

主题

12

主题

12

主题

童生

Rank: 1

积分
46
 楼主| 发表于 2013-1-26 15:51:45 | 显示全部楼层 |阅读模式
递归,常出现在声明式范式的语言中,用来实现过程迭代的语义;正如循环,常出现在命令式的语言中,用来实现数据迭代的语义。递归一般有两种:尾递归(tail recursion)与非尾部递归(non-tail recusion),后者因为需要保存大量的临时变量,一般不被采用。下面使用不同的语言写一个常见的例子,求阶乘。

1)使用Java求阶乘
// 非尾递归
public class Math {public static int fac(int n) {return n == 0 ? 1 : fac(n-1) * n; }public static void main(String[] args) {System.out.println(fac(5));}}

// 尾递归
public class Math {public static int fac(int result, int n) {return n == 0 ?  result : fac(result*n, n-1);}public static int fac(int n) {return fac(1, n);}public static void main(String[] args) {System.out.println(fac(5));}}

2)使用C/C++求阶乘
// 非尾递归(C)
#include <stdio.h>  #include <stdio.h>int fac(int n) {    return n == 0 ? 1 : fac(n-1) * n;}int main(int argc, char*argv[]) {      int result = fac(3);    printf("The result is %d ", result);     return 0;  }  

// 尾递归(C++)
#include <iostream> using namespace std; int fac(int result, int n) {return n == 0 ?  result : fac(result*n, n-1);}int fac(int n) {return fac(1, n);}int main(int argc, char*argv[]) {      int result = fac(3);    cout << "The result is " << result;     return 0;  }  

3)使用JavaScript求阶乘
// 非尾递归
// 这里提供了一些简单的谓词,以纯函数的风格表达递归
function div(a, b){  return a/b; } function dec(x){  return x - 1; } function equal(a, b){  return a==b; } function fac(n){      return equal(n, 1) ? 1 : mul(n, fac(dec(n))); } document.write(fac(3));

// 尾递归(版本1)
// 在这里,通过JavaScript中arguments模拟重载不适用,
// 简单起见,也不再多写一个函数封装fac(result, n)来简化其参数个数。
// 因为后面有更简洁的表达方法,即采用闭包和匿名函数技术。
function fac(result, n) {      return n == 0 ?  result : fac(result*n, n-1);  }  document.write(fac(1, 3));

//尾递归(版本2)
// 这里采用闭包技术,但内部函数为具名函数,因为递归时需要呼叫函数的名字。
function fac(n) {return (function fac(result, n) {return n == 0 ?  result : fac(result*n, n-1);})(1, n);}document.write(fac(5));

//尾递归(版本3)
// 这里采用闭包技术,内部函数之所以可以是匿名函数,是因为arguments.callee
// 即参数的被调用者的属性,可以引用匿名函数,在递归时可用来呼叫。
function fac(n) {return (function(result, n) {return n == 0 ?  result : arguments.callee(result*n, n-1);})(1, n);}document.write(fac(5));

4)使用Erlang求阶乘
// non-tail recursion
-module(math).-export([fac/1]).fac(1) -> 1;fac(N) -> N * fac(N - 1)

// tail recursion
-module(math).-export([fac/1]).fac(N) -> fac(1, N).fac(Result, 1) -> Result;fac(Result, N) -> fac(N * Result, N - 1).
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表