Udemy算法挑战题:递归函数实现数组单词全大写,求代码详解
递归实现数组单词大写函数详解
问题背景
我在Udemy的算法挑战里遇到一个需求:写一个递归函数把数组里的每个单词转成大写。官方给的解决方案我看不太懂,能不能帮我一步步拆解代码的执行过程和原理?
官方代码如下:
function capitalizeWords (array) { if (array.length === 1) { return [array[0].toUpperCase()]; } let res = capitalizeWords(array.slice(0, -1)); res.push(array.slice(array.length-1)[0].toUpperCase()); return res; }
核心原理拆解
递归的本质就是把大问题拆成小问题,直到小问题能直接解决,再把结果一步步合并,这个函数就是典型的递归思路:
1. 终止条件(递归的“出口”)
if (array.length === 1) { return [array[0].toUpperCase()]; }
当传入的数组只剩1个元素时,直接把这个元素转成大写,然后放进一个新数组返回——这是递归的终点,不能再拆了,直接给出结果。
2. 递归拆解大问题
let res = capitalizeWords(array.slice(0, -1));
array.slice(0, -1)的作用是截取原数组除了最后一个元素之外的所有元素,比如原数组是["hello", "world", "foo"],slice之后就变成["hello", "world"]。
然后我们调用capitalizeWords处理这个缩短后的数组——这就是递归的核心:把“处理3个元素的数组”拆成“处理2个元素的数组”,再拆成“处理1个元素的数组”,直到触发终止条件。
3. 合并结果
res.push(array.slice(array.length-1)[0].toUpperCase());
当递归调用返回结果(也就是缩短后的数组已经全部转成大写的数组),我们把原数组的最后一个元素转成大写,然后push到这个结果数组里,最后返回合并后的数组。
这里array.slice(array.length-1)是截取原数组的最后一个元素(返回的是一个只有一个元素的数组),所以[0]是取出这个元素,再转成大写。
用实际例子走一遍执行流程
假设我们调用capitalizeWords(["cat", "dog", "bird"]),一步步看:
- 第一次调用:数组长度是3,不满足终止条件。调用
capitalizeWords(["cat", "dog"]),等待它的返回结果。 - 第二次调用:数组长度是2,不满足终止条件。调用
capitalizeWords(["cat"]),等待返回结果。 - 第三次调用:数组长度是1,触发终止条件,返回
["CAT"]。 - 回到第二次调用:
res现在是["CAT"],然后把原数组的最后一个元素"dog"转成"DOG"push进去,res变成["CAT", "DOG"],返回这个数组。 - 回到第一次调用:
res现在是["CAT", "DOG"],把原数组的最后一个元素"bird"转成"BIRD"push进去,res变成["CAT", "DOG", "BIRD"],最终返回这个结果。
这样一步步递归拆解、合并,就完成了整个数组的单词大写转换。
内容的提问来源于stack exchange,提问作者Peter Staal
相关产品推荐
相关产品推荐

