如何使用递归函数替换?

时间:2017-08-04 01:50:00

标签: javascript recursion while-loop

我以这种方式使用while

while (value < -180 || value > 180) {
  if (value < -180) {
    value += 360
  }
  if (value > 180) {
    value -= 360
  }
}

但我想使用递归函数而不是while。我在Google上搜索过但无法find任何事情。所以我想也许我可以在这里得到答案。

2 个答案:

答案 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循环版本值