【问题标题】:Javascript: Multiplicative Persistence Problem Proposed Solution Execution Timing OutJavascript:乘法持久性问题提出的解决方案执行超时
【发布时间】:2019-08-27 09:43:43
【问题描述】:

我有以下问题:

编写一个函数,persistence,它接受一个正参数 num 并返回它的乘法持久性,这是您必须将 num 中的数字相乘直到达到单个数字的次数。

function persistence(num) {

  let count = 0; 
  let numStr = num.toString(); 

   if (numStr.length === 1){
     return 0
   } 

   if (numStr.length === 2){
     while (numStr.length > 1){
       count += 1
       numStr = (Number(numStr[0])*Number(numStr[1])).toString() 
     }
   }

   if (numStr.length === 3){
     while (numStr.length > 1){
       count += 1
       numStr = (Number(numStr[0])*Number(numStr[1])*Number(numStr[2])).toString() 
     }
   }

   return count 
}

persistence(999) //solution 4

我收到“执行超时(12000 毫秒)”错误。我知道有不同的方法可以解决这个问题,但我想具体了解我的代码有什么问题。

【问题讨论】:

  • 我看不出有任何不同if statments 的原因
  • 您的“3”案例假定字符串在循环中始终为 3 位数;不会的,所以你最终会得到NaN,而那永远是NaN(并且不止一个字符)。
  • while 循环的第一次迭代会得到9*9*9 = 729。然后是7*2*9 = 126,然后是1*2*6 = 12,然后是1*2*undefined = NaN,然后是'N'*'a'*'N' = NaN,然后是'N'*'a'*'N' = NaN,然后是'N'*'a'*'N' = NaN,以此类推。

标签: javascript function loops if-statement while-loop


【解决方案1】:

使用递归函数,您可以轻松完成:

只需添加一个新的 args count(这个函数被调用了多少次)并在结果长度超过 1 时调用它

function persistence(num, count) {
  count = count || 0; 
  let numStr = num.toString(); 
  
  if (numStr.length === 1) {
    return count
  } 
  let new_num = numStr.split('').reduce((acc, val) => {
    return acc * val
  }, 1)
  return persistence(new_num, count + 1) 
}

console.log("99", persistence(99))
console.log("999", persistence(999))
console.log("99999", persistence(99999))

【讨论】:

  • 你也可以跳过额外的参数和return persistence(new_num) + 1;,在地下室用return 0代替return count
  • 没有。因为return 0 会假设这是你第一次调用这个函数。 (或者我不明白)
  • @Paulpro 它的编写方式至少可以进行尾调用优化(尽管大多数 JS 运行时不这样做)
  • @Arthur 如果numStr.length === 1 第一次调用该函数,则正确答案为 0。
  • 它看起来像这样:jsfiddle.net/n64co98b 并且总是给出与你的函数相同的输出,但在我看来更容易理解,因为每个递归调用只是计算下一个的持久性号码。
【解决方案2】:

您的代码无法正常工作的原因是您总是将str[2] 添加到最终结果中。

999 > 729 > 126 > 12 > 2

所以在这里你看到一个循环号变成12str[2]undefined 并且它将是NaN 所以循环永远不会结束。

一种简单的方法是在while 中使用reduce(),而无需在乘法时将其转换为Number()

function persistence(num) {

  let count = 0; 
  num = String(num);
  while(num.length > 1){
    count++;
    num = String([...num].reduce((ac,a) => a * ac,1));
  }
  return count;
}

console.log(persistence(999))

【讨论】:

  • 好答案,但请不要使用x + '' 代替String(x)
  • @georg 我改变了它。我也想知道使用String(x)而不是x + ''的原因
  • @georg x + '' 是在 JavaScript 中强制转换为字符串的常用方法。没有很好的理由经常使用 String 构造函数。 num.toString() 会更好,但与空字符串连接可以说是最好的。
  • @Paulpro: String(x) 不是构造函数。
  • @georg Yes, it is。 (和:ecma-international.org/ecma-262/9.0/…)。你可以在没有new 的情况下调用它,但String 仍然是一个构造函数,无论你是否使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 2015-05-22
  • 2021-05-17
相关资源
最近更新 更多