【问题标题】:Fibonacci Sequence - Find the number of digits - JavaScript斐波那契数列 - 找出位数 - JavaScript
【发布时间】:2014-01-10 16:05:56
【问题描述】:

所以,我已经成功编写了斐波那契数列来创建带有数字序列的array,但我需要知道长度(多少位数500th 号码有。

我试过下面的代码,但它找到了科学记数法的长度(22 位),而不是它应该返回的正确的 105。

任何想法如何将科学记数法数字转换为实际整数?

var fiblength = function fiblength(nth) {
    var temparr = [0,1];
    for(var i = 2; i<=nth; i++){
        var prev = temparr[temparr.length-2],
            cur = temparr[temparr.length-1],
            next = prev + cur;
            temparr.push(next);
    }
    var final = temparr[temparr.length-1].toString().length;
    console.log(temparr[temparr.length-1]);
    return final;
};
a = fiblength(500);
console.log(a);

【问题讨论】:

  • 看看这是否有帮助stackoverflow.com/questions/4288821/…
  • 我混合了一些东西...... Bignum 库可能是 OP 需要的。
  • @thefourtheye:什么意思,这里没有浮点数? JavaScript 中的所有数字都是浮点数,它甚至没有整数类型。
  • @Amadan 我指的是当前问题。
  • @thefourtheye:我还是不明白。当前的问题是关于 JavaScript 中的数字。 JavaScript 中的所有数字都是浮点数。因此,这里有花车。我错过了什么?

标签: javascript fibonacci notation scientific-notation


【解决方案1】:

这是一个恒定时间的解决方案:

function fiblength(n) { 
   return Math.floor((n>1)?n*.2089+.65051:1); 
}

让我们解释一下我是如何做到的。

除非您有一个 BigNumber 库,否则所有以前的解决方案都可能不适用于 N&gt;300。他们也很无能。

有一个公式可以得到任何斐波那契数,它使用PHI(黄金比例数),非常简单:

F(n) = ABS((PHI^n)/sqrt(5))

PHI=1.61803399 的位置(黄金比例,在整个斐波那契数列中都可以找到)

如果您想知道一个数字有多少位,您可以计算以 10 为底的对数并在其上加 1。让我们调用这个函数D(n) = log10(n) + 1

所以你想要的fiblength 只是在下面的函数中

fiblength(n) = D(F(n)) // 斐波那契数的位数...

让我们计算一下,这样您就可以看到使用数学后的单行代码会是什么样子。

替换F(n)

fiblength(n) = D(ABS((PHI^n)/sqrt(5)))

现在在上面应用 D(n):

fiblength(n) = log10(ABS((PHI^n)/sqrt(5))) + 1

所以,因为log(a/b) = log(a) - log(b)

fiblength(n) = log10(ABS((PHI^n))) - log10(sqrt(5))) + 1

自从log(a^n) = n * log(a)

fiblength(n) = n*log10(PHI) - log10(sqrt(5))) + 1

然后我们评估这些对数,因为它们都是常数 并添加 n=0n=1 的特殊情况以返回 1

function fiblength(n) { 
   return Math.floor((n>1)?n*.2089+.65051:1); 
}

享受:)

fiblength(500) =&gt; 105 //不需要迭代。

【讨论】:

    【解决方案2】:

    问题是因为在进行任何有意义的计算之前,结果数字已转换为字符串。以下是在原始代码中可以解决的方法:

    var fiblength = function fiblength(nth) {
        var temparr = [0,1];
        for(var i = 2; i<=nth; i++){
            var prev = temparr[temparr.length-2],
                cur = temparr[temparr.length-1],
                next = prev + cur;
                temparr.push(next);
        }
        var x = temparr[temparr.length-1];
        console.log(x);
        var length = 1;
        while (x > 1) {
            length = length + 1;
            x = x/10;
        }
        return length;
    };
    
    console.log ( fiblength(500) );
    

    【讨论】:

    • 我喜欢避免内置数学函数来调整它的方法。最后一点,你需要做 return length-1;返回正确的值;-)
    【解决方案3】:

    我的最终解决方案

    function fiblength(nth) {
        var a = 0, b = 1, c;
        for(var i=2;i<=nth;i++){
            c=b;
            b=a+b;
            a=c;
        }
        return Math.floor(Math.log(b)/Math.log(10))+1;
    }
    console.log(fiblength(500));
    

    感谢您的帮助!!!

    【讨论】:

      【解决方案4】:

      为什么不使用简单的除以 10 直到小于 1 的过程。

      像这样简单的东西应该可以工作(递归 def obv 也可以)

      function getDigits(n) {
         var digits = 0;
         while(n >= 1) {
            n/=10;
            digits += 1;
         }
         return digits;
      }
      
      getDigits(200);//3
      getDigits(3.2 * 10e20);//=>22
      

      【讨论】:

      • 或者你可以得到 10 基对数。 Math.floor(Math.log(n) / Math.log(10)) + 1 应该足够了。
      • 我们开始吧。这是一种非常优雅的方式来完成这项工作......很漂亮:-) 不是 100% 我需要的,而是很好的跳板:-) 谢谢!
      【解决方案5】:

      大多数 javascript 实现在内部使用 64 位数字。因此,如果我们试图表示的数字非常大,它会使用科学计数法来表示这些数字。因此,没有基于纯“javascript 数字”的解决方案。您可能需要寻找其他 BigNum 库。

      就您的代码而言,您只需要第 500 个数字,因此您不必将整个数字数组存储在内存中,只需之前和当前的数字就足够了。

      function fiblength(nth) {
          var previous = 0, current = 1, temp;
          for(var i = 2; i<=nth; i++){
              temp = current;
              current = previous + current;
              previous = temp;
          }
          return current;
      };
      

      【讨论】:

      • 在一个循环中除以 10 并添加一个计数器来跟踪它这样做的次数往往可以解决问题。但是,非常感谢最小化我的代码:-)
      猜你喜欢
      • 2014-05-19
      • 2015-06-05
      • 2021-11-30
      • 2015-01-04
      • 1970-01-01
      相关资源
      最近更新 更多