【问题标题】:recursive function output weird values递归函数输出奇怪的值
【发布时间】:2017-04-04 16:43:52
【问题描述】:

我正在尝试使用 JavaScript 在 codewars 中完成一个 kata,这些是说明:

斐波那契数是以下整数序列 (Fn) 中的数字: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ... 如 F(n) = F(n-1) + F(n-2) 其中 F(0) = 0 且 F(1) = 1。 给定一个数字,比如说 prod(对于产品),我们搜索 两个斐波那契数 F(n) 和 F(n+1) 验证 F(n) * F(n+1) = 产品。 您的函数 productFib 接受一个整数 (prod) 并返回一个数组: [F(n), F(n+1), true] 或 {F(n), F(n+1), 1} 或 (F(n), F(n+1), True) 如果 F(n) * F(n+1) = prod,则取决于语言。 如果你没有找到两个连续的 F(m) 验证 F(m) * F(m+1) = prod 你会回来的 [F(m), F(m+1), 假] 或 {F(n), F(n+1), 0} 或 (F(n), F(n+1), 假) F(m) 是最小的一个,例如 F(m) * F(m+1) > prod。 例子 productFib(714) # 应该返回 [21, 34, true], # 因为 F(8) = 21, F(9) = 34 和 714 = 21 * 34 productFib(800) # 应该返回 [34, 55, false], # 因为 F(8) = 21, F(9) = 34, F(10) = 55 和 21 * 3

好吧,我只需要创建一个斐波那契数列并返回数组,这是我的代码:

function productFib(prod) {
    return fib(0, 1, prod);
}
function fib(a, b, prod) {
    if (a * b < prod) {
        return (a + b) + fib(b, a + b, prod);
    }
    else if (a * b == prod) {
        return [a, b, true];
    }
    else {
        return [a, b, false];
    }
}

这是一个递归斐波那契数列,但是,当我运行它时,我没有得到预期的数组,结果是正确的,变量具有正确的值等等,但是当返回数组时,我得到一个很长的第一个元素,看起来它包含整个斐波那契系列。 这是一个测试用例:(productFib(4895), [55, 89, true])

如果我使用该测试运行我的代码,我会得到以下结果:

productFib(4895)
"12358132134558955,89,true"

你们能解释一下那里发生了什么吗?

【问题讨论】:

  • fib() 有时会返回一个数组,该数组最终作为+ 的操作数,将其转换为字符串。

标签: javascript recursion fibonacci


【解决方案1】:

只需从您的返回值中删除(a + b) +

替换

 return (a + b) + fib(b, a+b, prod);

 return fib(b, a+b, prod);

【讨论】:

  • “什么”没有“为什么”才有用。
  • 我同意,这不是最好的答案,我必须管理我专注于快速提供帮助,因为我知道在做 katas 时没有发现错误是多么令人沮丧。
【解决方案2】:

您的 fib 函数有一种情况,它返回单个非数组值:

return (a + b) + fib(b, a+b, prod);

...以及它返回对数组的引用的两种情况:

return [a,b,true];
// and
return [a,b,false];

第一个在+ 操作中使用返回值。这会将数组强制转换为一个字符串,该字符串会生成一个逗号分隔的条目列表,并将其转换为字符串,然后进行字符串连接。

您可能不想在return 中进行字符串连接。只需将其更改为return fib(b, a + b, prod); 似乎就可以解决问题:

function productFib(prod) {
  return fib(0, 1, prod);
}

function fib(a, b, prod) {
  if (a * b < prod) {
    return fib(b, a + b, prod);
  } else if (a * b == prod) {
    return [a, b, true];
  } else {
    return [a, b, false];
  }
}
console.log(productFib(4895)); // [55, 89, true]

【讨论】:

  • 这将解决奇怪的输出,但代码仍然是错误的——他必须在他过去时“回滚”。他的代码没有这样做。我仍然给 +1,因为这是 OP 不理解的大问题。
  • @Hogan:如果您想进一步了解答案,我已将帖子设为社区 Wiki... :-)(我向您保证,您比我更了解斐波那契数列。 ..)
  • 实际上我认为这是正确的,因为我刚刚重新阅读了要求并且他希望第一个等于或大于 - 这确实......出于某种原因我认为等于或小于。
  • @Hogan:很容易做到。 :-)
  • 非常感谢!!我认为它有时可能与返回数组有关,但没有考虑串联,非常感谢您的解释,我现在看到了我的错误。
猜你喜欢
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多