Генерация последовательности Фибоначчи - PullRequest
23 голосов
/ 30 октября 2011
var x=0, 
var y=1;
var z;

fib[0] = 0;
fib[1] = 1;
for(i=2; i<=10; i++)
{
    alert(x+y);
    fib[i]=x+y;
    x=y;
    z=y;
}

Я пытаюсь сгенерировать простую последовательность Фибоначчи, но нет вывода. Кто-нибудь может дать мне знать, что не так?

Ответы [ 39 ]

0 голосов
/ 12 апреля 2016

Начинающий, не слишком элегантный, но показывает основные шаги и выводы в JavaScript

/* Array Four Million Numbers */
var j = [];
var x = [1,2];
var even = [];
for (var i = 1;i<4000001;i++){
   j.push(i);
    }
// Array Even Million
i = 1;
while (i<4000001){
    var k = j[i] + j[i-1];
    j[i + 1]  = k;
    if (k < 4000001){
        x.push(k);
        }
    i++;
    }
var total = 0;
for (w in x){
    if (x[w] %2 === 0){
        even.push(x[w]);
        }
 }
for (num in even){
    total += even[num];
 }
console.log(x);
console.log(even);
console.log(total); 
0 голосов
/ 17 апреля 2018

Вот функция, которая полностью отображает сгенерированную последовательность Фибоначчи при использовании рекурсии:

function fibonacci (n, length) {
    if (n < 2) {
        return [1];   
    }
    if (n < 3) {
        return [1, 1];
    }

    let a = fibonacci(n - 1);
    a.push(a[n - 2] + a[n - 3]);
    return (a.length === length) 
            ? a.map(val => console.log(val)) 
            : a;

};

Выход для fibonacci(5, 5) будет:

1
1
2
3
5

Значение, присвоенное a, является возвращенным значением функции fibonacci. В следующей строке вычисляется следующее значение последовательности Фибоначчи, которое передается в конец массива a.

Параметр length функции fibonacci используется для сравнения длины последовательности, являющейся массивом a, и должен совпадать с параметром n. Когда длина последовательности соответствует параметру длины, массив a выводится на консоль, в противном случае функция возвращает массив a и повторяется.

0 голосов
/ 18 апреля 2017

Вы можете использовать рекурсию и функционально кэшировать результаты.

const fibonacci = (n, cache = {1: 1, 2: 1}) =>
  cache[n] || (cache[n] = fibonacci(--n, cache) + fibonacci(--n, cache));
  
console.log(fibonacci(1000));
console.log(fibonacci(100));
console.log(fibonacci(10));
0 голосов
/ 10 мая 2018

Еще одна реализация, хотя рекурсивная очень быстрая и использует единственную встроенную функцию. Он достигает предела точности 64-битных чисел javascript, начиная 80-ю последовательность (как и все остальные алгоритмы): Например, если вы хотите 78-й член (78 идет в последней скобке):

(function (n,i,p,r){p=(p||0)+r||1;i=i?i+1:1;return i<=n?arguments.callee(n,i,r,p):r}(78));

вернет: 8944394323791464

Это обратно совместимо вплоть до ECMASCRIPT4 - я протестировал его с IE7, и он работает!

0 голосов
/ 19 апреля 2017
function fibo(count) {

    //when count is 0, just return 
    if (!count) return;

    //Push 0 as the first element into an array
    var fibArr = [0];

    //when count is 1, just print and return
    if (count === 1) {
        console.log(fibArr);
        return;
    }

    //Now push 1 as the next element to the same array
    fibArr.push(1);

    //Start the iteration from 2 to the count
    for(var i = 2, len = count; i < len; i++) {
        //Addition of previous and one before previous
        fibArr.push(fibArr[i-1] + fibArr[i-2]);
    }

    //outputs the final fibonacci series
    console.log(fibArr);
}

Какой бы подсчет нам ни понадобился, мы можем дать его выше fibo и получить ряд Фибоначчи до подсчета.

fibo(20); //output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
0 голосов
/ 02 июня 2018
var a = -1;
var b=0;
var temp =0;
var arry = [];
for(var i=1;i<100;i++){
    temp = a+b;
    a=b;
    b=temp;
    arry.push(b*-1);
}
console.log(arry);
0 голосов
/ 20 мая 2017

Я думаю, что этот достаточно прост, чтобы понять:

function fibonacci(limit) {
    let result = [0, 1];

    for (var i = 2; i < limit; i++) {
        result[result.length] = result[result.length - 1] + result[result.length - 2];
    }

    return result;

}
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
console.log(fibonacci(10));
0 голосов
/ 18 октября 2018

Мне нравится тот факт, что есть так много способов создать последовательность Фибоначчи в JS .Я постараюсь воспроизвести некоторые из них.Цель состоит в том, чтобы вывести последовательность на консоль (например, {n: 6, fiboNum: 8})

Good 'ol closure

// The IIFE form is purposefully omitted. See below.

const fiboGenClosure = () => {
  let [a, b] = [0, 1];
  let n = 0;
  return (fiboNum = a) => {
    [a, b] = [b, a + b];
    return {
      n: n++,
      fiboNum: fiboNum
    };
  };
}

// Gets the sequence until given nth number. Always returns a new copy of the main function, so it is possible to generate multiple independent sequences.

const generateFiboClosure = n => {
  const newSequence = fiboGenClosure();
  for (let i = 0; i <= n; i++) {
    console.log(newSequence());
  }
}

generateFiboClosure(21);

Необычный генератор ES6

Аналогично схеме замыкания, приведенной выше, с использованием преимуществ функции генератора и для ... цикла.

// The 'n' argument is a substitute for index.

function* fiboGen(n = 0) {
  let [a, b] = [0, 1];
  while (true) {
    yield [a, n++];
    [a, b] = [b, a + b];
  }
}

// Also gives a new sequence every time is invoked.

const generateFibonacci = n => {
  const iterator = fiboGen();
  for (let [value, index] of iterator) {
    console.log({
      n: index,
      fiboNum: value
    });
    if (index >= n) break;
  }
}

generateFibonacci(21);

Рекурсия вызова Tail

Это немного сложно, потому что, в конце 2018 года, оптимизация TC все еще остается проблемой.Но, честно говоря - если вы не будете использовать какие-либо хитрые трюки, чтобы позволить стандартному движку JS использовать действительно большие числа, у него закружится голова и он скажет, что следующим числом Фибоначчи будет «Бесконечность» на итерации 1477. Возможно, стек где-то переполнитсявокруг итерации 10 000 (сильно зависит от браузера, памяти и т. д.).Вероятно, может быть дополнен блоком try… catch или проверьте, достигнут ли «Infinity».

const fibonacciRTC = (n, i = 0, a = 0, b = 1) => {
  console.log({
    n: i,
    fibonacci: a
  });
  if (n === 0) return;
  return fibonacciRTC(--n, ++i, b, a + b);
}

fibonacciRTC(21)

Он может быть записан как однострочный, если мы отбросим вещь console.log и просто вернем число:

const fibonacciRTC2 = (n, a = 0, b = 1) => n === 0 ? a : fibonacciRTC2(n - 1, b, a + b);

console.log(fibonacciRTC2(21))

Важное примечание!

Как я узнал, прочитав эту статью mathIsFun , последовательность Фибоначчи действительна для отрицательных чисела также! Я попытался реализовать это в приведенной выше форме рекурсивного вызова:

const fibonacciRTC3 = (n, a = 0, b = 1, sign = n >= 0 ? 1 : -1) => { 
  if (n === 0) return a * sign;
	return fibonacciRTC3(n - sign, b, a + b, sign);
}

console.log(fibonacciRTC3(8)); // 21
console.log(fibonacciRTC3(-8)); // -21
0 голосов
/ 10 июля 2016

Вот еще один с правильным хвостовым вызовом.

Рекурсивная внутренняя функция fib может повторно использовать стек, потому что все, что нужно (массив чисел) для получения следующего числа, передается в качестве аргумента, никаких дополнительных выражений для оценки.

Однако в ES2015 введена оптимизация вызовов.

Также одним недостатком является то, что он получает длину массива в каждой итерации (но только один раз) для генерации следующего числа и получения элементов массива по их индексу (хотя это быстрее, чем pop, splice или другие методы массива), но Я не тестировал производительность всего решения.

var fibonacci = function(len) {
  var fib = function(seq) {
    var seqLen = seq.length;
    if (seqLen === len) {
      return seq;
    } else {
      var curr = seq[seqLen - 1];
      var prev = seq[seqLen - 2];
      seq[seqLen] = curr + prev;
      return fib(seq);
    }
  }
  return len < 2 ? [0] : fib([0, 1]);
}

console.log(fibonacci(100));
...