S1 : 递归

  递归函数是在一个函数通过名字调用自身的情况下构成的,如下所示

function f(num){
    if(num<=1){
         return 1;
    } else {
         return num*f(num-1);
    }
}

这是一个经典的递归阶乘函数。虽然这个函数表面看来没什么问题,但下面的代码却可能导致它出错

var a = f;
f = null;
a(3);//出错

以上代码先把f()函数保存在变量a 中,然后将f 变量设置为null,结果指向原始函数的引用只剩下一个。但在接下来调用a()时,由于必须执行f(),而f 已经不再是函数,所以就会导致错误。在这种情况下,使用arguments.callee 可以解决这个问题。我们知道,arguments.callee是一个指向正在执行的函数的指针,这样就可以实现递归调用了:

function f(num){
    if(num<=1){
         return 1;
    } else {
         return num*arguments.callee(num-1);
    }
}

通过使用arguments.callee 代替函数名,可以确保无论怎样调用函数都不会出问题。因此,在编写递归函数时,使用arguments.callee 总比使用函数名更保险。但在严格模式下,不能通过脚本访问arguments.callee,访问这个属性会导致错误。不过,可以使用命名函数表达式来达成相同的结果。例如:

var g = (function f(num){
    if(num<=1){
        return 1;
    } else {
        return num*f(num-1);
    }
});

以上代码创建了一个名为f()的命名函数表达式,然后将它赋值给变量g。即便把函数赋值给了另一个变量,函数的名字f 仍然有效,所以递归调用照样能正确完成。这种方式在严格模式和非严格模式下都行得通

时间: 2024-10-16 06:26:43

S1 : 递归的相关文章

BF匹配算法

/*BF算法,即普通模式匹配算法,将字符串与标准模板进行一位一位匹配, * 一旦失败,就将字符串第一个字符去掉,重新匹配*/ package pack; import java.util.Scanner; public class Main { static int count = 0; //存放匹配的位数 public static void main(String[] args) { Scanner in = new Scanner(System.in); String s = in.nex

二叉树的非递归遍历--京东2015笔试回忆

题目回忆: C/C++研发试卷:偏重于数据结构的考察,编程题有2题+1题附加题: 1.输入整数n,求m,m>9,m中各个数位的乘积=n的最小整数;如n=36,m=49; 2.二叉树前序遍历的非递归实现(本文的总结) 3.求第n个数,这个序列满足(2^i)*(3^j)*(5^k),前7个为:2,3,4,5,6,8,10 .... 小题有基本的数据结构.程序运行结果.SQL题目. 4.删除表格用DROP命令,死锁产生的条件: 4.1互斥使用(资源独占) 一个资源每次只能给一个进程使用 4.2.不可强

数据结构——二叉树遍历之“递归与非递归遍历”

简述 二叉树的遍历分为先序遍历.中序遍历和后序遍历.如下图所示: 递归遍历 private void bianli1(List<Integer> list, TreeNode root) { // 先序遍历 if (root == null) { return; } list.add(root.val); bianli1(list, root.left); bianli1(list, root.right); } private void bianli2(List<Integer>

C程序语法(无左递归)

C程序语法(无左递归) <程序> -〉 <外部声明> | <函数定义><外部声明> -〉<头文件> | <变量> | <结构体> <头文件> -〉 #include<文件名><文件名> -〉 stdio.h丨stdlib.h丨string.h<结构体> -〉 <结构体声明〉|<变量><结构体声明> -〉 struct<标识符><

递归(c++)(转)

1.什么是递归函数(recursive function) 递归函数即自调用函数,在函数体内部直接或间接地自己调用自己,即函数的嵌套调用是函数本身. 例如,下面的程序为求n!: long fact(int n) { if(n==1) return 1: return fact(n-1)*n: //出现函数自调用 } 2.函数调用机制的说明 任何函数之间不能嵌套定义, 调用函数与被调用函数之间相互独立(彼此可以调用). 发生函数调用时,被调函数中保护了调用函数的运行环境和返回地址,使得调用函数的状

递归和迭代两种方式实现归并排序(Java版)

递归版 package MergeSort; import Utils.SortUtils; /** * 归并排序递归版 * @author liguodong */ public class Demo02 { public static void mergeSort(int[] a){ mSort(a, a, 0, a.length-1); } /** * * @param SR为待排序的数据 * @param TR1为排序之后的数据 * @param s * @param t */ publ

紫书第4章 函数和递归

1  序 系统的整理下第四章的学习笔记.同上次一样,尽量在不依赖书本的情况下自己先把例题做出来.这次有许多道题代码量都比较大,在例题中我都用纯C语言编写,但由于习题的挑战性和复杂度,我最终还是决定在第五章开始前,就用C++来完成习题.不过所有的代码都是能在C++提交下AC的. 在习题中,我都习惯性的构造一个类来求解问题,从我个人角度讲,这会让我的思路清晰不少,希望自己的一些代码风格不会影响读者对解题思路的理解. 其实在第四章前,我就顾虑着是不是真的打算把题目全做了,这些题目代码量这么大,要耗费很

字符串中的匹配之递归

字符串的括号匹配是一个很常见的问题.用栈这种后进先出的结构是非常适合的.此外,字符串中的回文以及衍生的各种问题也是字符串处理中非常常见的. 今天再说一下这类相似的问题,如何用递归来转化成子结构来求解. 先放一条LeetCode例题: 680. Valid Palindrome II Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome

二叉树的遍历,递归和非递归

import java.util.ArrayDeque; import java.util.Stack; class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int val) { this.val = val; } } public class BinaryTree { //先序遍历递归 public static void preOrder(TreeNode