`
mindfocus
  • 浏览: 16999 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

递归(Recursion)

阅读更多
    递归,常出现在声明式范式的语言中,用来实现过程迭代的语义;正如循环,常出现在命令式的语言中,用来实现数据迭代的语义。递归一般有两种:尾递归(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).
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics