简体   繁体   English

递归不仅仅是一个函数本身

[英]More to Recursion than Just a Function Calling Itself

Every textbook I've ever seen on recursive functions uses the factorials as an example, which is helpful but not totally illuminating. 我所见过的有关递归函数的每本教科书都以阶乘为例,这虽然很有帮助,但并不能完全说明问题。

For programming purposes, can a recursive function take a function as its base case, can it include other function calls within its body, or can it execute differently at different levels of recursion? 出于编程目的,递归函数可以将某个函数作为其基本情况,可以在其主体中包含其他函数调用,还是可以在不同的递归级别上以不同的方式执行?

And if it does these any of these things, is it still a 'recursive function' or is it now something else? 而且,如果它做这些事情中的任何一件,它是否仍然是一个“递归函数”或现在是其他东西?

The definition of a recursive function is simply "a function that calls itself". 递归函数的定义就是“调用自身的函数”。 So if you have a function that calls itself, it is a recursive function. 因此,如果您有一个调用自身的函数,则它是一个递归函数。

Anything else simply depends on the capabilities of the language you're working with. 其他任何事情都仅取决于您使用的语言的功能。

This is a fairly straightforward example of a recursive function that simply outputs all of the values in a collection, an array represented as a stack, to the browser console as it pops them off of the stack using the .pop() method. 这是一个相当简单的递归函数示例,该函数简单地将集合中的所有值(表示为堆栈的数组)输出到浏览器控制台,因为它使用.pop()方法将其从堆栈中弹出。

The totalSize value doesn't change throughout the entire call stack so that it can be used to measure the halfway point by dividing the current stack size by the original size. totalSize值在整个调用堆栈中不会改变,因此可以通过将当前堆栈大小除以原始大小来测量中途点。

To answer the question of can it behave differently at different levels in the recursion, the answer is yes: 要回答在递归中不同级别上行为是否不同的问题,答案是肯定的:

// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];

// recursive function that calls itself. It behaves slightly different at
 // the halfway point
function test(totalSize, col) {
    if(col == undefined || col.length == 0) {
        return 0;

     } else {
        if(col.length / totalSize < .5) {
            console.log("Past 1/2 way point!");
        }
        console.log("total = " + totalSize);
        console.log("col.pop() = " + col.pop());
        return test(totalSize, col);
    }
}

// make a call to the function with the total size and the collection
test(coll.length, coll);

Additionally, you also asked if it were possible to call other functions, this is also possible. 此外,您还询问是否可以调用其他函数,这也是可能的。 In the example below, a function is used to return the result of the base case, and a function is used to abstract the halfway point behavior: 在下面的示例中,一个函数用于返回基本情况的结果,而一个函数则用于抽象中途行为:

// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];

// recursive function that calls itself. It behaves slightly different at
 // the halfway point
function test(totalSize, col) {
    if(col == undefined || col.length == 0) {
        return handleBaseCase(totalSize, col);

     } else {
        // handle if it's at 1/2 way point
        handleHalfwayPoint(totalSize, col);  

        console.log("tital = " + totalSize);
        console.log("col.pop() = " + col.pop());
        return test(totalSize, col);
    }
}

function handleHalfwayPoint(totalSize, collection) {
    if(collection.length / totalSize < .5) {
        console.log("Past 1/2 way point!");
    }
}

// instead of returning 0, return "Done" and also print to the log
function handleBaseCase(totalSize, collection) {
    console.info("Done!");
    return "Done!";
}

// make a call to the function with the total size and the collection
test(coll.length, coll);

While these particular examples don't solve any real-world problem, it demonstrates how the concept of calling a function inside another function could expand to handle other use-cases. 尽管这些特定示例无法解决任何现实问题,但它演示了如何在另一个函数中调用一个函数的概念可以扩展为处理其他用例。 The examples in your textbook are simply designed to teach you the basics of recursion and help arm you with the tools necessary to take on more complex, real-world problems in the future. 教科书中的示例仅旨在教您递归的基础知识,并帮助您配备必要的工具,以解决将来遇到的更复杂的实际问题。

Since this functional language is JavaScript, the barriers to running them are low. 由于此功能语言是JavaScript,因此运行它们的障碍很低。 You can try these examples by running the code in the Chrome Developer Console, or you could run them in a small test HTML file. 您可以通过在Chrome开发者控制台中运行代码来尝试这些示例,也可以在一个小的测试HTML文件中运行它们。 Good luck! 祝好运!

A recursive function is a function that calls itself one or more times in its body. 递归函数是在其主体中调用自身一次或多次的函数。 Functions can also be mutually recursive, where one function is defined in terms of the second, or vice-versa. 函数也可以是相互递归的,其中一个函数是根据第二个定义的,反之亦然。

I've been programming for over 20 years without the need for recursion. 我已经进行了20多年的编程,无需递归。 What made me really understand the need, as well as the beauty, of recursive calls was the Scheme language, and books such as "The little Schemer". 使我真正了解递归调用的必要性和妙处的是Scheme语言和诸如“ The Little Schemer”之类的书。

Not all programming languages support recursion at the same level. 并非所有的编程语言都支持同一级别的递归。 Scheme is one of those who do it very well. 计划是做得很好的人之一。 Python much less so. Python要少得多。 So if you want to dive into recursion, check the abilities of your programming language. 因此,如果您想深入研究递归,请检查您的编程语言的功能。

As other answers have said, a recursive function is a function that calls itself. 正如其他答案所言,递归函数是一个调用自身的函数。 There are two types as explained here : 有两种类型的解释在这里

  1. Direct recursion: in which the function calls itself. 直接递归:函数在其中调用自身。
  2. Indirect recursion: when a function is called not by itself but by another function that it called (either directly or indirectly). 间接递归:当一个函数不是由其本身而是由其调用的另一个函数(直接或间接)调用时。

I see the math tag in your question. 我在您的问题中看到了数学标记。 Recursion is related to math induction. 递归与数学归纳有关。 If you prove that it can solve the base case and then you prove that if any one statement in the infinite sequence of statements is true, then so is the next one, you prove that it will solve the problem in any case. 如果您证明它可以解决基本情况,然后证明如果无数个语句序列中的任何一个语句为真,那么下一个语句也是如此,那么您将证明它可以解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM