斐波那契序列JavaScript的第n个值(超时错误)

斐波那契序列JavaScript的第n个值(超时错误),javascript,algorithm,while-loop,fibonacci,Javascript,Algorithm,While Loop,Fibonacci,对于这个Kata(查找Fibonacci序列的第n个值),我有一个有效的解决方案,但是我一直得到一个超时错误。有人能就如何重构它以更高效地运行提供建议吗?提前谢谢 以下是带有说明的链接- 给定三个非负整数a、b和n,并使无穷序列与斐波那契序列一样,使用以下规则: 步骤1:使用ab作为初始顺序。 步骤2:计算两个参数的总和 序列的最后两位,并将其附加到序列的末尾。 重复步骤2 您的任务是完成函数find。 返回序列的第n位(基于0) 函数查找(a、b、n){ 让我们开始=(“”+a+b); 设n

对于这个Kata(查找Fibonacci序列的第n个值),我有一个有效的解决方案,但是我一直得到一个超时错误。有人能就如何重构它以更高效地运行提供建议吗?提前谢谢

以下是带有说明的链接-

给定三个非负整数a、b和n,并使无穷序列与斐波那契序列一样,使用以下规则:

步骤1:使用ab作为初始顺序。 步骤2:计算两个参数的总和 序列的最后两位,并将其附加到序列的末尾。 重复步骤2 您的任务是完成函数find。 返回序列的第n位(基于0)

函数查找(a、b、n){
让我们开始=(“”+a+b);
设next=a+b;
让seq=开始+下一步;

而(seq.length首先…不要使用字符串,不要使用
parseInt
,不要同时保留整个序列。您只需要数字,只需要最后两位数字。给定一个介于10和18之间的数字
x
(这是两位数字的最大可能总和),它的十位数是
1
,一位数是
x-10
。仅此一点就将是一个显著的改进

其次……由于给定点后的整个序列由该点的前两位数字决定,1并且只有100个可能的两位数字序列,因此每个序列必须在200位以内重复;也就是说,最多在200位以内,它必然会进入一个重复数字的循环,它永远不会离开,其中循环长度小于200位。2因此,如果
n
大于几百位,您可以通过查找此循环的长度并“跳过”该长度的大倍数来进行大规模优化

1.事实上,这并不完全正确。例如,序列69156…和79167…包含91,但后跟不同的内容。这是因为“1”属于一个两位数,其两位数都由前两位数决定。我不确定如何更好地表达这一点,但希望你明白我的意思。它是esn不会影响整体论点,但在应用想法时需要小心。

2.实际上要少得多;测试a和b的所有可能值,我发现序列总是进入循环并在25位以内完成其第一次迭代!但我不确定如何严格证明这个小得多的数字,而不是穷举测试;因此,以依赖它的方式编写代码可能是欺骗

首先…不要使用字符串,不要使用
parseInt
,不要同时保留整个序列。您只需要数字,只需要最后两位数字。给定一个介于10和18之间的数字
x
(这是两位数字的最大可能和),它的十位数是
1
,一位数是
x-10
。仅此一点就将是一个显著的改进

其次……由于给定点后的整个序列由该点的前两位数字决定,1并且只有100个可能的两位数字序列,因此每个序列必须在200位以内重复;也就是说,最多在200位以内,它必然会进入一个重复数字的循环,它永远不会离开,其中循环长度小于200位。2因此,如果
n
大于几百位,您可以通过查找此循环的长度并“跳过”该长度的大倍数来进行大规模优化

1.事实上,这并不完全正确。例如,序列69156…和79167…包含91,但后跟不同的内容。这是因为“1”属于一个两位数,其两位数都由前两位数决定。我不确定如何更好地表达这一点,但希望你明白我的意思。它是esn不会影响整体论点,但在应用想法时需要小心。

2.实际上要少得多;测试a和b的所有可能值,我发现序列总是进入循环并在25位以内完成其第一次迭代!但我不确定如何严格证明这个小得多的数字,而不是穷举测试;因此,以依赖它的方式编写代码可能是欺骗

转换和执行字符串操作时,速度通常较慢

function nextVal(num){
    const last = (num%10);
    const lastButOne = (num - last)/10 % 10;
    const sum = last + lastButOne;
    return sum < 10 ? num * 10 + sum : num *100 + sum;
}
function find(a,b,n){
  let num = a * 10 + b;
  const above = Math.pow(10, n);// anything less than we don't have enough digits


  while (num < above) {
    num = nextVal(num);
  }
  return Number(`${num}`.charAt(n));
}
函数nextVal(num){
const last=(数值%10);
常量lastButOne=(num-last)/10%10;
常数和=最后一个+最后一个;
返回和<10?num*10+和:num*100+和;
}
函数查找(a、b、n){
设num=a*10+b;
const over=Math.pow(10,n);//任何小于的数字都没有足够的数字
while(num<以上){
num=nextVal(num);
}
返回编号(`${num}`.charAt(n));
}

上面的代码依赖于数字检查,只将其转换为字符串(这也是可以避免的)

当您转换和执行字符串操作时,通常速度较慢

function nextVal(num){
    const last = (num%10);
    const lastButOne = (num - last)/10 % 10;
    const sum = last + lastButOne;
    return sum < 10 ? num * 10 + sum : num *100 + sum;
}
function find(a,b,n){
  let num = a * 10 + b;
  const above = Math.pow(10, n);// anything less than we don't have enough digits


  while (num < above) {
    num = nextVal(num);
  }
  return Number(`${num}`.charAt(n));
}
函数nextVal(num){
const last=(数值%10);
常量lastButOne=(num-last)/10%10;
常数和=最后一个+最后一个;
返回和<10?num*10+和:num*100+和;
}
函数查找(a、b、n){
设num=a*10+b;
const over=Math.pow(10,n);//任何小于的数字都没有足够的数字
while(num<以上){
num=nextVal(num);
}
返回编号(`${num}`.charAt(n));
}

上面的代码依赖于数字检查,只将其转换为字符串(这也是可以避免的)

这里是Codewars链接-
函数find(a,b,n){return 5;}
?不确定速度,但您的答案只是碰巧正确。您需要分别对每个字符串进行
parseInt
分析。您不断地在字符串末尾添加
15
。@MarkMeyer您完全正确-已编辑代码以反映该更改。但是,我尝试了它