如果每次进行递归调用时var如何设置回其初始值,如何使用递归来保持计数器var的值

时间:2018-02-27 15:39:31

标签: javascript recursion

我是编程的新手,特别是js,我正在解决一个问题,我必须返回一个给定数字(参数)需要乘以其数字的次数,直到它变成一位数字(小于10)。我知道我的一般逻辑除计数器外都有效。我无法找到一种方法来保持其以前的递归调用的值(不修改我传递给函数本身的参数数量)。它总是被设置回0.我的逻辑中是否有任何明显的缺失?

到目前为止我的代码:

function persistence(num) {
   var countTimes  = 0;   // it will always go back to zero here 
   var numToArr = String(num).split('').map(nums => Number(nums));
   var resultOfMultNumDigits = numToArr.reduce(function (a,b) {return a * b},1);
   if (resultOfMultNumDigits < 10){
     return countTimes; 
   }else {
   countTimes += 1;  // increases here every time the case base isn't reach
   return persistence(resultOfMultNumDigits);
   }
}  

4 个答案:

答案 0 :(得分:3)

TL; DR

使用递归时,有一个&#34;计数器&#34;变量可以是代码气味。通常在递归代码中,您想要的结果是 this &#34; iteration中的某些操作的结果,&#34;结合 next 迭代的结果(结合 next 的结果,等等......)。

当你想要的结果只是迭代次数时,递归函数的最后一行(myFunc)通常如下所示:return 1 + myFunc(dataForNextIteration);。这就是这里的情况(我们假设toDigitsproduct是执行他们在锡上所说的功能):

function persistence(num) {
  const digits = toDigits(num);
  if (digits.length === 1) {
    return 0;
  }
  return 1 + persistence(product(digits));
}

如何到达那里

我们想要计算&#34;迭代&#34; ()。如果从0开始,迭代后的结果应为。如果输入是一位数字,我们的工作就完成了,所以我们只返回0而不进行进一步的递归。这是开始编写代码的好地方。

function persistence(num) {
  const digits = toDigits(num);
  if (digits.length === 1) {
    return 0;
  }

  // ...
}

这是我们的&#34;停止案例&#34;:一位数?停止递归并返回0

如果digits.length大于1怎么办?当然,我们希望获得digits的产品并将其传递给下一个&#34;迭代&#34; persistence。但是我们如何处理结果?

假设num为123.其数字的乘积为6,即一位数。然后,我们知道, next 迭代将触及我们的停止案例并返回0。这意味着迭代应该返回1。我们如何从1获得0?添加1

function persistence(num) {  // num => 123
  const digits = toDigits(num);  // digits => [1, 2, 3];
  if (digits.length === 1) {  // digits.length => 3
    return 0;
  }

  const digitsProduct = product(digits);  // digitsProduct => 6
  const nextResult = persistence(digitsProduct);  // nextResult => 0
  return 1 + nextResult;  // 1 + 0
}

为了示范,这有点冗长。你可以在下面的工作片段中看到它不那么冗长:

&#13;
&#13;
function toDigits(num) {
  return String(num).split('').map(n => parseInt(n));
}

function product(arr) {
  return arr.reduce((prod, n) => prod * n, 1);
}

function persistence(num) {
  const digits = toDigits(num);
  if (digits.length === 1) {
    return 0;
  }
  return 1 + persistence(product(digits));
}

// ...or terser still...
function persistence(num) {
  const d = toDigits(num);
  return d.length === 1 ? 0 : 1 + persistence(product(d));
}

console.log(persistence(5)); // => 0
console.log(persistence(123)); // => 1
console.log(persistence(1234)); // => 2
console.log(persistence(123456)); // => 2
console.log(persistence(999)); // => 4
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以返回一个带有count和value的对象,并为每次递归递增第一部分。

function persistence(num) {
    var value = num.toString().split('').reduce((a, b) => a * b, 1),
        temp;

    if (value < 10){
        return { count: 0, value };
    }
    temp = persistence(value);
    temp.count++;
    return temp;
}

console.log(persistence(2222222));
console.log(persistence(22222));
console.log(persistence(22));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

您似乎正在尝试计算乘法根和持久性 - 我already answered this question here

&#13;
&#13;
const digits = n =>
  n < 10
    ? [ n ]
    : digits (n / 10 >> 0) .concat ([ n % 10 ])

const mult = (x,y) =>
  x * y

const product = xs =>
  xs.reduce (mult, 1)

const multiplicativeRoot = x =>
  x < 10
    ? [ x ]
    : [ x ] .concat (multiplicativeRoot (product (digits (x))))
  
const multiplicativePersistence = x =>
  multiplicativeRoot (x) .length - 1
  
console.log (multiplicativeRoot (999))        // [ 999, 729, 126, 12, 2 ]
console.log (multiplicativePersistence (999)) // 4

console.log (multiplicativeRoot (25))         // [ 25, 10, 0 ]
console.log (multiplicativePersistence (25))  // 2
&#13;
&#13;
&#13;

答案 3 :(得分:-1)

  

...不修改我传递给函数本身的参数数量......

有你的解决方案。如果您需要更多参数用于递归,请引入它们。要获得附加参数的初始值,实际上要编写两个函数 - 一个具有所需参数的递归函数,以及一个具有从外部使用的签名的函数。然后从公开函数调用辅助函数。