【问题标题】:Multiplicative Persistence Codewars Challenge乘法持久性代码战挑战
【发布时间】:2019-02-18 20:58:25
【问题描述】:

我一直在研究 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,我似乎无法弄清楚为什么,任何帮助将不胜感激。

【问题讨论】:

  • 如果您要问为什么第二段代码会这样,最好不要通过显示其他代码来混淆问题。此外,两段代码都使用for 循环,均未显示while....
  • 另外,发布的代码会产生不同的结果,因为 count 仅在第一次运行时设置为 0...
  • 第二个函数不好,它依赖于全局变量count,所以它根据调用的时间给出不同的结果。应该重写为return 0return 1 + persistence(...) 并且根本不使用全局count
  • 我在 Stack Overflow 上遇到了这里提出的解决方案 - 一个链接可能会有用。另外,你问为什么别人的代码不起作用?
  • @HereticMonkey 抱歉,我发布了错误的代码,但我现在已将其删除,因为我知道它为什么会令人困惑。

标签: javascript


【解决方案1】:

贴出的代码有不少问题。

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

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

另一个问题是它应该使用i &lt;,而不是i &lt;=,否则最终的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)
);

【讨论】:

    【解决方案2】:

    或者我们可以使用while循环和reduce数组方法

    const persistence=(num)=>{
    
      let splitNumArr=num.toString().split('')
      let newList
      let count=0
      while(splitNumArr.length>1){
    
         newList=splitNumArr.reduce((acc,curr)=>{
            return acc*=curr
         })
          splitNumArr=newList.toString().split('')
          count++
    
      }
    
    return count
    }
    
    
    
    console.log(persistence(39))===3
    console.log(persistence(999))===4
    console.log(persistence(9))===0
    

    【讨论】:

      最近更新 更多