将明确的循环转换为递归解决方案的“通用公式”如下:
很难概括任何旧的循环如何替换为递归,但这可以用作一般指南:
对于具有以下形式的循环:
var a, b, c = ...;
while (condition) {
// Change a, b, c...
}
// Use a, b, c
您可以将其转换为:
function recursive(a, b, c...) {
if (!condition) {
return [a, b, c...];
} else {
return recursive(a', b', c'...);
}
}
对于你的例子,这将看起来像这样:
function recur(value) {
if (value > -180 || value < 180) {
return value;
} else if (value < -180) {
return recur(value + 360);
} else {
return recur(value - 360);
}
}
在你需要再次循环的情况下,递归运用,但需要记住必须返回递归的结果。而在想要结束循环的情况下,需返回累加器。注意每个执行分支都必须以一个返回结束。只要你放弃递归的结果(未返回)就会导致数据丢失。
请注意:
如我在评论中提到的那样,递归不是应该用于任何问题的通用方法,尤其是当语言不支持优化时。它可能适用于小问题,但是在问题变得更大时,你可能会发现它突然开始引起“堆栈溢出”的问题。
当处理可变数据时,递归可能会变得困难和令人困惑。如果你的累加器是可变的(列表、映射或任何其他非原始数据类型),则必须非常小心地设置所有内容。相同的数据将能够从每个递归分支进行访问和更改。如果你不小心,则会以很难调试的方式更改你的累加器。如果你想走递归/函数式路线,我建议你查看像Immutable.js这样的库,或者类似Clojurescript这样几乎只涉及不可变结构的语言。Clojurescript可以编译成JavaScript。
while
。 - alex