Генерация последовательности Фибоначчи - 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 ]

51 голосов
/ 13 августа 2015

В соответствии с вопросом Интервью Торт , последовательность идет 0,1,1,2,3,5,8,13,21 .Если это так, то это решение работает и является рекурсивным без использования массивов.

function fibonacci(n) {
   return n < 1 ? 0
        : n <= 2 ? 1
        : fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(4));

Думайте об этом так.

   fibonacci(4)   .--------> 2 + 1 = 3
      |          /               |
      '--> fibonacci(3) + fibonacci(2)
            |    ^           
            |    '----------- 2 = 1 + 1 <----------.
1st step -> |                     ^                |
            |                     |                |
            '---->  fibonacci(2) -' + fibonacci(1)-'

Обратите внимание, это решениене очень эффективен, хотя.

46 голосов
/ 30 октября 2011

Вы никогда не объявляли fib массивом.Для решения этой проблемы используйте var fib = [];.

Кроме того, вы никогда не изменяете переменную y и не используете ее.

Приведенный ниже код имеет больше смысла, плюс, он не делаетсоздать неиспользуемые переменные:

var i;
var fib = []; // Initialize array!

fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
  // Next fibonacci number = previous + one before previous
  // Translated to JavaScript:
  fib[i] = fib[i - 2] + fib[i - 1];
  console.log(fib[i]);
}
20 голосов
/ 01 июля 2013

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

fib = function(numMax){
    for(var fibArray = [0,1], i=0,j=1,k=0; k<numMax;i=j,j=x,k++ ){
        x=i+j;
        fibArray.push(x);
    }
    console.log(fibArray);
}

fib(10)

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

15 голосов
/ 30 октября 2011

Сначала вы должны были объявить переменную fib как массив (например, var fib = [] или var fib = new Array()), и я думаю, вы немного запутались в алгоритме.
Если выиспользуйте массив для хранения последовательности Фибоначчи, вам не нужны другие вспомогательные переменные (x,y,z):

var fib = [0, 1];
for(var i=fib.length; i<10; i++) {
    fib[i] = fib[i-2] + fib[i-1];
}
console.log(fib); 

Нажмите для демонстрации

Вы должнырассмотрим рекурсивный метод (обратите внимание, что это оптимизированная версия):

function fib(n, undefined){
    if(fib.cache[n] === undefined){
        fib.cache[n] = fib(n-1) + fib(n-2);
    }

    return fib.cache[n];
}
fib.cache = [0, 1, 1];

, а затем, после вызова функции Фибоначчи, у вас есть вся последовательность в поле fib.cache:

fib(1000);
console.log(fib.cache);
12 голосов
/ 20 октября 2015

Еще один ответ - использовать функции генератора es6 .

function* fib() {
  var current = a = b = 1;

  yield 1;

  while (true) {
    current = b;

    yield current;

    b = a + b;
    a = current;
  }
}

sequence = fib();
sequence.next(); // 1
sequence.next(); // 1
sequence.next(); // 2
// ...
9 голосов
/ 30 октября 2011

Вы не присваиваете значение z, так что вы ожидаете от y=z;?Точно так же вы никогда не читаете из массива.Похоже, что вы пробуете комбинацию двух разных подходов здесь ... попробуйте полностью избавиться от массива и просто используйте:

// Initialization of x and y as before

for (i = 2; i <= 10; i++)
{
    alert(x + y);
    z = x + y;
    x = y;
    y = z;
}

РЕДАКТИРОВАТЬ: ОП изменил код после того, как я добавилэтот ответПервоначально последняя строка цикла была y = z; - и это имеет смысл , если вы инициализировали z согласно моему коду.

Если массивтребуется позже, тогда, очевидно, это необходимо заполнить еще - но в противном случае код, который я дал, должен быть в порядке.

6 голосов
/ 22 марта 2017

Золотой рацион "phi" ^ n / sqrt (5) асимптотичен фибоначчи n, если округлить это значение, мы действительно получим значение Фибоначчи.

function fib(n) {
    let phi = (1 + Math.sqrt(5))/2;
    let asymp = Math.pow(phi, n) / Math.sqrt(5);

    return Math.round(asymp);
}

fib(1000); // 4.346655768693734e+208 in just 0.62s

Это работает быстреев больших количествах по сравнению с рекурсивными решениями.

3 голосов
/ 15 июля 2016
function fib(n) {
  if (n <= 1) {
    return n;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

fib(10); // returns 55
2 голосов
/ 01 ноября 2016

Я просто хотел бы внести свой вклад в версию ES6, оптимизированную для хвостовых вызововЭто довольно просто;

var fibonacci = (n, f = 0, s = 1) => n === 0 ? f : fibonacci(--n, s, f + s);
console.log(fibonacci(12));
2 голосов
/ 25 января 2016

При использовании es6

function fib(n, prev = 0, current = 1) {
  return !n ? prev + current : fib(--n, current, prev+current)
}


var f = fib(10)
...