递归名称
问题描述:
我有点迷路了,但如果有人能简单地解释一下为什么这段代码能起作用,那会很棒!递归名称
// Our array of messy words
var capitals = ["berlin", "parIs", "MaDRiD"];
// Capitalize function
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}
// Our recursive function
function fixLetterCase(array, i) {
// Base case
if (i === array.length) {
return;
}
// Action
array[i] = capitalize(array[i]);
// Recursive case
return fixLetterCase(array, i + 1);
}
// Here is our function call
fixLetterCase(capitals, 0);
console.log(capitals);
答
虽然我知道这不是一个问题的答案,我想这可能有助于看逻辑的非递归版本:
// Our array of messy words
var capitals = ["berlin", "parIs", "MaDRiD"];
// Simple function to capitalize word
function fixLetterCase(array) {
for(var i = 0; i < array.length; i++) {
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1).toLowerCase();
}
}
fixLetterCase(capitals);
console.log(capitals);
答
function fixLetterCase(array, i) {
// At some point, this is true, so the algorithm stops
if (i === array.length) { return; }
// At this point, the function did not returned. The function logic continues.
// Replace the array key with a new value = the return value of captialize()
array[i] = capitalize(array[i]);
// i increments by one, and the function itself is called again.
return fixLetterCase(array, i + 1);
}
// Initialize the function, with starting offset ("counter") i=0
fixLetterCase(capitals, 0);
答
函数fixLetterCase
被调用i
等于零。当fixLetterCase
第一次运行时,它会在数组中的第一个字上调用capitalize
。在递归调用中,它使用1来递增i
,这意味着它将大写数组中的下一个单词。它将继续这样做直到它到达数组的末尾。
这就是为什么函数可以工作:需要大写的单词的索引每增加一次,在最后一次调用时,当索引等于数组长度时,'递归'结束。
请注意,这不是递归的典型用法,因为递归调用没有任何返回。还要注意,这可以写得更直接一个for循环。
答
这确实不需要recursivly写的,你可以做同样的事情
// Our array of messy words
var capitals = ["berlin", "parIs", "MaDRiD"];
// Capitalize function
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}
// Our recursive function
function fixLetterCase(array, i) {
// Action
array[i] = capitalize(array[i]);
}
// Here is our function call
for(var i = 0; i < capitals.length; i++)
{
fixLetterCase(capitals, i);
}
console.log(capitals);
递归部分只能通过资本迭代的话,当你到达数组末尾逃逸。希望像这样阅读会更清楚。
答
// Our recursive function
function fixLetterCase(array) {
for (var i = 0, length = array.length; i < length; i++) {
array[i] = capitalize(array[i]);
}
}
可能是一个更好,更具可读性,更高性能的解决方案。这种情况根本不需要递归,循环应该更有效。你不需要那么多的函数调用,并且你不需要在每次函数调用时评估数组的长度。
答
我假设你谈论递归部分。这实际上只是迭代数组的一种奇特方式。
按照惯例,你可以这样做有for
循环,下面的模式(原谅完全怪异的伪代码,我自己总的发明):
for ([initialization]; [condition]; [modification])
[function]
递归,你可以做到这一点为:
[function [initialization]]
if [!condition]
break
[function [modification]]
我个人觉得在这种情况下递归版本没有太大的好处,因为它更少地道,因此不太明显。并没有提供性能优势。
你究竟在哪里卡住了? – 2012-04-03 14:43:04
我只是不明白所发生的一切。这很令人困惑 – Sam 2012-04-03 14:55:53
但你知道这是递归。所以,你至少知道*某事*。那么,代码的哪一部分看起来对你来说很神奇?你需要什么来更好地理解代码? – 2012-04-03 14:56:58