`
mindfocus
  • 浏览: 17562 次
  • 性别: 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).
分享到:
评论

相关推荐

    递归Recursion)1

    标题提到的"递归Recursion)1"可能是指一个关于递归的系列教程或讨论的第一个部分,重点是介绍递归的基本概念和QL中的应用。 描述中提到了一个使用递归谓词`getANumber()`的例子,这个谓词用于生成0到100之间的所有...

    用Python解决数据结构和算法(高清带详细目录书签)

    本手册主要是了解计算机科学、程序设计和问题解决的基本概念;理解什么是“抽象”以及抽象在问题解决过程中的作用;...递归 Recursion 119 5.排序与搜索 .158 6.树和树算法 .191 7.图和图算法 .259

    C# 实现汉诺塔问题 递归+Recursion

    在这个问题中,C#编程语言被用来解决这个问题,利用了递归的思想。本文将详细讲解如何用C#实现汉诺塔问题以及递归的概念。 首先,理解递归是非常关键的。递归是一种算法或函数调用自身的方法,通常用于解决可以分解...

    数据结构与算法-单路递归 Single Recursion

    ### 数据结构与算法-单路递归:深入理解与应用 #### 1. 算法与数据结构的基础概念 ##### 1.1 什么是算法? 算法是在数学和计算机科学领域中的一系列有限且严谨的指令集合,这些指令通常被设计用于解决特定类型的...

    Recursion递归程序设计

    下面我们将深入探讨递归的本质、递归函数、递归执行、尾递归以及递归与迭代的关系。 首先,理解递归的性质是至关重要的。递归通常包含一个或多个基础(或边界)情况,这些情况可以直接解决而不需要进一步的递归调用...

    apachecn#Interview#递归_recursion1

    同样有趣的例子 吃完一个bowl of chips:for loop,知道多少薯片,然后从0开始吃到最后递归,吃一片,然后继续吃剩下的 N - 1 片,直到碗里

    消除左递归

    消除左递归 编译原理是计算机科学中的一门重要课程,涉及到计算机语言的设计、实现和应用。消除左递归是编译原理中的一项重要技术,旨在消除 Context-Free Grammar 中的左递归,生成等价的文法。 一、什么是左...

    LeetCode算法蛇形走位-leetcode_way:leetcode解决方案的降价

    recursion math 快慢双指针 stack set 二分查找 scan DP,fibonacci recursion DP 中序遍历 recursion 递归 recursion DP recursion or math math math DP DP 递归?回溯+减支? dfs recursion map (归并排序) math ...

    lyj2014211626#Prepare_For_AI_Job#leetcode-22. 括号生成1

    22. 括号生成参考博客1力扣上不错的解解法1:回溯+剪枝对于这种列出所有结果的题首先还是考虑用递归 Recursion 来解,由于字符串只有左括号和右括号两种

    asp.net递归运算的例子

    ASP.NET递归运算是一种在编程中解决复杂问题的策略,它涉及到函数或方法调用自身来解决问题。在ASP.NET框架中,递归可以用于处理树形结构数据、遍历文件系统、实现算法(如Fibonacci序列)等多种场景。本案例提供了...

    ejemplos_recursion_recursion_C++_Examples_

    在这个名为 "ejemplos_recursion_recursion_C++_Examples_" 的资源包中,我们有两个文件:ejemplos_recursion.cc 和 libropre3.pdf,它们提供了关于 C++ 中递归的实例和可能的理论解释。 首先,ejemplos_recursion....

    消除左递归得到后缀式.rar_Left Recursion_后缀式 文法_消除左递归

    消除左递归是将含有左递归的文法转换为等价但不含左递归的文法的过程。常见的方法包括直接法和间接法。直接法是将左递归的产生式A → αAβ转换为两个新产生式:A → αB和B → Aβ,其中B是一个新非终结符。这个...

    计算递归函数调用次数

    为了避免这种情况,可以考虑使用尾递归(Tail Recursion)、记忆化(Memoization)或迭代(Iteration)等优化方法。 尾递归是指在递归调用的最后返回结果,这样编译器或解释器有可能优化掉多余的栈帧,减少内存消耗...

    栈和递归遍历实例

    而递归(Recursion)则是一种函数自我调用的技术。在递归过程中,一个问题被分解为一个或多个规模更小的相同问题,直到问题变得足够简单可以直接解决。递归需要一个明确的基线条件(Base Case),以防止无限循环,...

    Julia:一个 Julia 程序的聚合

    Julia 代码聚合 ... 递归Recursion c. 变换等价Equivalent Transformation 2. 如果知道什么其他好的开源Julia 代码,欢迎联系! If any other open-sourced Julia codes are known, it is welcomed to co

    递归实现字符串反向输出

    递归(Recursion)是指在一个函数的定义或执行过程中直接或间接地调用自身的一种方法。递归通常包含两个关键部分:**基本情况**(Base Case)和**递归情况**(Recursive Case)。 - **基本情况**:这是递归结束的...

    c实现消除文法左递归

    C语言实现消除文法左...最后,我们在main函数中读取文法 productions,并将其传递给eliminate_left_recursion函数以消除左递归。 使用C语言实现消除文法左递归是编译原理中的一种重要技术,可以提高语法分析的效率。

    详解python使用递归、尾递归、循环三种方式实现斐波那契数列

    递归是最直观的实现方式,就像题目中给出的 `Fib_recursion` 函数所示。它通过不断调用自身来计算数列中的某一项。然而,递归方法的效率较低,因为它会重复计算许多已经计算过的值,随着n的增大,时间复杂度呈指数...

    如何考虑算法-循环不变式和递归How to Think About Algorithms - Loop Invariants and Recursion

    本文将探讨循环不变式和递归两种关键算法技术,它们帮助学生抽象地思考问题,并发展出专家级别的算法描述和思维能力。 循环不变式是分析算法中循环的正确性的一种方法。它是一种数学性质,在循环的每次迭代中都成立...

    recursion-effect-0.0.3-win64_OBS_recursion_

    总的来说,"recursion-effect-0.0.3-win64_OBS_recursion_"提供了一个用于OBS的递归特效插件,允许用户在他们的直播或视频制作中创新性地使用递归原理,创造出引人入胜的视觉体验。为了充分利用这个工具,用户需要...

Global site tag (gtag.js) - Google Analytics