我以这种方式使用while
:
while (value < -180 || value > 180) {
if (value < -180) {
value += 360
}
if (value > 180) {
value -= 360
}
}
但我想使用递归函数而不是while
。我在Google上搜索过但无法find任何事情。所以我想也许我可以在这里得到答案。
答案 0 :(得分:2)
将显式循环转换为递归解决方案的“通用公式”是:
弄清楚循环的“累加器”是什么。通常,循环将操纵一个或两个值,并且这些值是循环的“结果”。
使累加器成为函数的参数。
很难概括如何用递归替换任何旧循环,但这可以作为一般指导原则:
对于具有以下形式的循环:
function recursive(a, b, c...) {
// When the condition does *not* hold, end the recursion.
// Note that condition is negated relative to the while-loop.
if (!condition) {
// Base case.
return [a, b, c...];
} else {
// Change a, b, c...
// and recurse with the new values
return recursive(a', b', c'...);
}
}
您可以将其转换为:
function recur(value) {
if (value > -180 || value < 180) {
return value; // Base case
} else if (value < -180) {
return recur(value + 360);
} else {
return recur(value - 360);
}
}
对于您的示例,这看起来像:
{{1}}
如果您希望再次循环,请递归,但请记住您需要返回递归结果。对于要结束循环的情况,请返回累加器。请注意,每个执行分支必须以返回结束。一旦你丢弃递归的结果(不返回它),数据就会丢失。
请注意:
正如我在评论中提到的那样,递归并不是一个应该抛出任何旧问题的锤子;特别是当语言没有针对它进行优化时。对于小问题可能没什么问题,但是在未来的道路上,当问题变得更大时,你可能会发现它会突然开始导致StackOverflows无处不在。
在处理可变数据时,递归会变得困难和混乱。如果你的累加器是 mutable (列表,地图或任何其他非原始的),你必须非常小心你如何设置一切。可以从递归的每个分支访问并更改相同的数据。如果您不小心,您将以非常难以调试的方式将您的累加器从您的下方更换。如果你想进入递归/功能路径,我建议你研究一下像Immutable.js这样的库,或者像Clojurescript那样几乎只处理不可变结构的语言。 Clojurescript编译成JavaScript。
答案 1 :(得分:1)
试试这个:
var recur_num = recursion(500)
console.log(recur_num)
var while_num = viaLoop(500)
console.log(while_num)
function recursion(value) {
if (value < -180) {
return recursion(value + 360);
}
if(value > 180){
return recursion(value - 360);
}
if (value > -180 || value < 180) {
return value;
}
}
function viaLoop(value){
while (value < -180 || value > 180) {
if (value < -180) {
value += 360
}
if (value > 180) {
value -= 360
}
}
return value;
}
您可以比较递归版本值和while循环版本值