while 循环后的条件语句适用于大多数测试但不是全部(斐波那契数学逻辑问题)
Conditional statement after while loop working for most tests but not all (Fibonacci math logic problem)
正在研究 JavaScript 关于 codewars challenge here
中的斐波那契数列的问题
到目前为止,这是我的代码:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
firstFib = firstFib + secondFib
secondFib = firstFib + secondFib
}
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
除了两个测试:productFib(193864606) 和 productFib(602070),我已经通过了所有测试。我的结果分别是 [10946, 17711, false] 和 [610, 987, false],他们应该说 true 而不是 false。但是,如果您将这些斐波那契数相乘,它们就等于 prod 参数,所以我不明白为什么我的条件语句没有专门捕获这两个数。
您的逻辑需要稍作改动。你获得配对的方式是:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
firstFib = firstFib + secondFib
secondFib = firstFib + secondFib
console.log(firstFib,secondFib);
}
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
productFib(602070);
你的配对是:
0,1
1,2
3,5
但是您错过了 2,3
或 1,1
应该在一起的情况。
那是因为您正在将 firstFib
更新为 firstFib + secondFib
。相反,它应该直接采用 secondFib
的值
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
let prevFirstFib = firstFib;
firstFib = secondFib;
secondFib = prevFirstFib + secondFib;
console.log(firstFib, secondFib);
}
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
console.log(productFib(602070));
console.log(productFib(193864606));
有两个问题:
第一个循环在每次迭代中跳转 2 个斐波那契阶梯。但是应该保留两者中最大的斐波那契数,并作为两者中最小的。
else
部分不应回溯到前一对。当前对是您需要 return。因此,您甚至可以在没有 if..else
的情况下执行此操作,并将相等性检查作为布尔参数传递。
更正:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
[firstFib, secondFib] = [secondFib, firstFib + secondFib]
}
return [firstFib, secondFib, prod === firstFib*secondFib]
}
const assertSimilar = (a, b) => console.assert(JSON.stringify(a) === JSON.stringify(b));
assertSimilar(productFib(4895), [55, 89, true])
assertSimilar(productFib(5895), [89, 144, false])
assertSimilar(productFib(74049690), [6765, 10946, true])
assertSimilar(productFib(84049690), [10946, 17711, false])
assertSimilar(productFib(193864606), [10946, 17711, true])
assertSimilar(productFib(447577), [610, 987, false])
assertSimilar(productFib(602070), [610, 987, true])
console.log("tests passed");
如果你加入一些日志语句,就会更容易看到发生了什么。你的函数实际上失败了一个小得多的数字 - 40。输入一些日志记录,让我们看看发生了什么:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
console.log("before", firstFib, secondFib);
firstFib = firstFib + secondFib
secondFib = firstFib + secondFib
console.log("after", firstFib, secondFib);
}
console.log(prod, firstFib, secondFib)
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
console.log(productFib(40))
如您所见,它正在跳过一个数字。而不是使用以前的 secondFib
作为新的 firstFib
它完全跳过它,这就是你的功能失败的原因。解决此问题的一个简单方法是保存之前的 firstFib
值,设置 firstFib = secondFib
,然后设置 secondFib = prevFirst + secondFib
,如下所示:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
console.log("before", firstFib, secondFib);
let prevFirst = firstFib;
firstFib = secondFib
secondFib = prevFirst + secondFib
console.log("after", firstFib, secondFib);
}
console.log(prod, firstFib, secondFib)
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
console.log(productFib(40))
现在您会看到它正确地遍历数字并输出您期望的结果!
正在研究 JavaScript 关于 codewars challenge here
中的斐波那契数列的问题到目前为止,这是我的代码:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
firstFib = firstFib + secondFib
secondFib = firstFib + secondFib
}
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
除了两个测试:productFib(193864606) 和 productFib(602070),我已经通过了所有测试。我的结果分别是 [10946, 17711, false] 和 [610, 987, false],他们应该说 true 而不是 false。但是,如果您将这些斐波那契数相乘,它们就等于 prod 参数,所以我不明白为什么我的条件语句没有专门捕获这两个数。
您的逻辑需要稍作改动。你获得配对的方式是:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
firstFib = firstFib + secondFib
secondFib = firstFib + secondFib
console.log(firstFib,secondFib);
}
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
productFib(602070);
你的配对是:
0,1
1,2
3,5
但是您错过了 2,3
或 1,1
应该在一起的情况。
那是因为您正在将 firstFib
更新为 firstFib + secondFib
。相反,它应该直接采用 secondFib
的值
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
let prevFirstFib = firstFib;
firstFib = secondFib;
secondFib = prevFirstFib + secondFib;
console.log(firstFib, secondFib);
}
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
console.log(productFib(602070));
console.log(productFib(193864606));
有两个问题:
第一个循环在每次迭代中跳转 2 个斐波那契阶梯。但是应该保留两者中最大的斐波那契数,并作为两者中最小的。
else
部分不应回溯到前一对。当前对是您需要 return。因此,您甚至可以在没有if..else
的情况下执行此操作,并将相等性检查作为布尔参数传递。
更正:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
[firstFib, secondFib] = [secondFib, firstFib + secondFib]
}
return [firstFib, secondFib, prod === firstFib*secondFib]
}
const assertSimilar = (a, b) => console.assert(JSON.stringify(a) === JSON.stringify(b));
assertSimilar(productFib(4895), [55, 89, true])
assertSimilar(productFib(5895), [89, 144, false])
assertSimilar(productFib(74049690), [6765, 10946, true])
assertSimilar(productFib(84049690), [10946, 17711, false])
assertSimilar(productFib(193864606), [10946, 17711, true])
assertSimilar(productFib(447577), [610, 987, false])
assertSimilar(productFib(602070), [610, 987, true])
console.log("tests passed");
如果你加入一些日志语句,就会更容易看到发生了什么。你的函数实际上失败了一个小得多的数字 - 40。输入一些日志记录,让我们看看发生了什么:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
console.log("before", firstFib, secondFib);
firstFib = firstFib + secondFib
secondFib = firstFib + secondFib
console.log("after", firstFib, secondFib);
}
console.log(prod, firstFib, secondFib)
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
console.log(productFib(40))
如您所见,它正在跳过一个数字。而不是使用以前的 secondFib
作为新的 firstFib
它完全跳过它,这就是你的功能失败的原因。解决此问题的一个简单方法是保存之前的 firstFib
值,设置 firstFib = secondFib
,然后设置 secondFib = prevFirst + secondFib
,如下所示:
function productFib(prod){
let firstFib = 0;
let secondFib = 1;
while (prod > firstFib * secondFib){
console.log("before", firstFib, secondFib);
let prevFirst = firstFib;
firstFib = secondFib
secondFib = prevFirst + secondFib
console.log("after", firstFib, secondFib);
}
console.log(prod, firstFib, secondFib)
if (prod === firstFib*secondFib){
return [firstFib, secondFib, true]
} else {
firstFib = secondFib - firstFib;
secondFib = secondFib - firstFib;
return [firstFib, secondFib, false]
}
}
console.log(productFib(40))
现在您会看到它正确地遍历数字并输出您期望的结果!