首页 > 解决方案 > 乘法持久性代码战挑战

问题描述

我一直在研究 Codewars 的一个 kata,挑战是编写一个函数,持久性,它接受一个正参数 num 并返回它的乘法持久性,这是你必须将 num 中的数字相乘直到你达到的次数一个数字。

例子:

persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
                       // and 4 has only one digit

persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
                        // 1*2*6 = 12, and finally 1*2 = 2

persistence(4) === 0 // because 4 is already a one-digit number

在试图弄清楚这一点时,我在网上遇到了一个解决方案(如下所示),在尝试理解它的逻辑之后,我看不出为什么代码不起作用

var count = 0;

function persistence(num) {
  if (num.toString().length === 1) {
    return count;
  }
  count++;
  var mult = 1;
  var splitStr = num.toString().split("");
  for (var i = 0; i <= splitStr; i++) {
    mult *= parseFloat(splitStr[i])
  }
  return persistence(parseFloat(mult));
}

任何一位数字的输出都是 0,这是正确的,但是对于任何多位数的数字,持久性总是记录为 1,我似乎无法弄清楚为什么,任何帮助将不胜感激。

标签: javascript

解决方案


发布的代码有很多问题。

for (var i = 0; i <= splitStr; i++) {

但是splitStr是一个数组,而不是一个数字;i <= splitStr没有意义。它应该检查splitStr.length而不是splitStr.

另一个问题是它应该使用i <,而不是i <=,否则最终splitStr[i]将是undefined

另一个问题是count变量是全局的,所以多次调用persistence会导致结果不准确。根本不需要count变量。要解决这个问题:

function persistence(num) {
  if (num.toString().length === 1) {
    return 0;
  }
  var mult = 1;
  var splitStr = num.toString().split("");
  for (var i = 0; i < splitStr.length; i++) {
    mult *= parseFloat(splitStr[i])
  }
  return 1 + persistence(parseFloat(mult));
}

console.log(
  persistence(999),
  persistence(39),
  persistence(4)
);

或者,可以完全避免for循环,并使用更合适的数组方法:

function persistence(num) {
  const str = num.toString();
  if (str.length === 1) {
    return 0;
  }
  const nextNum = str.split('').reduce((a, b) => a * b, 1);
  return 1 + persistence(nextNum);
}

console.log(
  persistence(999),
  persistence(39),
  persistence(4)
);


推荐阅读