2016-06-12 13 views
0

1と2で始まるフィボナッチシーケンスの最初の5つの数字を印刷したいと思います。ボタンをクリックしたときにこのコードが1,2,3,5,8と表示されると思いますが、この場合、8である。その後も何度もボタンをクリックすると、常に2が印刷されます。なぜそれはそのように振る舞うのですか?フィボナッチシーケンスの実装が期待通りに動作しない

/* 
 
Fibonacci sequence is calculated by the formula An = An-1 + An-2 
 
@param prev An-2 
 
@param next An-1 
 
@param n the first n numbers to print 
 
*/ 
 
var count = 0; // keeps track of which number we are on 
 
function fibonacci(prev, next, n) { 
 
    // Need to subtract 2 or else it will print the first 7 numbers instead of 5 
 
    return count++ < n - 2 ? fibonacci(Math.max(prev,next), prev+next, n) + "," : next; 
 
} 
 

 
document.querySelector('button').addEventListener('click', function() { 
 
    console.log(fibonacci(1, 2, 5)); 
 
});
<button>Click me</button>

+3

ヒント:ここで、 'count'をリセットしますか? – BeyelerStudios

+0

より正確に '8 ,,,'を表示します – 1983

+0

あなたは文字列に 'prev'を追加していません。 – 1983

答えて

2

あなただけの最後の結果でconsole.logを使用しています。それらのすべてをログに記録する場合は、再帰関数内で使用する必要があります。

ボタンを2回クリックすると、countがグローバルであるため、ボタンがクリックされません。イベントリスナ内で0にリセットすることはできますが、グローバルを避けるほうが効果的です。

function fibonacci(current, next, n) { 
 
    if(n > 0) { 
 
    console.log(current); 
 
    fibonacci(next, current + next, n-1); 
 
    } 
 
} 
 
document.querySelector('button').addEventListener('click', function() { 
 
    fibonacci(1, 2, 5); 
 
});
<button>Click me</button>

+2

OPの結果として単一の文字列が必要なようです。おそらくそのバリエーションが含まれていますか? 'var fib = function(a、b、n){return n === 1? a:a + '、' + fib(b、a + b、n-1); }; ' – 1983

+0

これはまさに私が必要としていたものです。オリオールと@FizzyTeaありがとう – Dummy

1

正確に一つの番号であるあなたconsole.log()fibonacci(1,2,5)の戻り値、。あなたは再帰関数呼び出しのどこにでも何も印刷しません。したがって、あなたの機能の最終結果のみが印刷されることは明らかです。 仲介の結果を希望される場合は、console.log(prev)の返信前にfibonacci()に記入してください。

これはあなたの最初の問題を解決します。


第2の問題については、変数の仕組みを覚えておく必要があります。 countはファンクションfibonacciの外に定義されているため、関数が終了しただけで自動的にリセットされたり何もされません。これは、ファンクションが初めて実行された後(そして副作用としてcount3に設定された)、変数countは値3を保持します。次回にこの機能を実行すると、4 < 3はfalseであるため、count++ < n - 2はすぐにfalseと評価されます。したがって、nextが返されます。これは最初の反復で2です。この問題を解決するには

、それはnextを返す前に(あなたは三元の文の中にこれを行うことはできません、最後の再帰が行われたときに、それは0countをリセットする方法であなたの機能をrestrucutre、あなたがあれば定期的にそれをrefractoreする必要があります-else)

+0

非常に良い説明。どうもありがとうございました。 +1。 – Dummy

0

最新のテクノロジーを使用しましょう。

<!DOCTYPE html> 
<html> 
<head> 
    <title>Fibonacci</title> 
    <meta charset="utf-8" /> 
    <script type="text/javascript"> 
     'use strict'; 
     function* fibonacci(cur, nxt) {//generator function 
      //let cur=0,nxt=1; 
      yield cur; 
      yield nxt; 
      while(true){ 
       [cur,nxt]=[nxt,cur+nxt];//swap 
       yield nxt; 
      } 
     } 

     function getNumbers(){ 
      var a = document.getElementById('cur').value-0;//instead of parseInt 
      var b = document.getElementById('nxt').value-0; 
      var n = document.getElementById('cnt').value-0; 
      var fi = fibonacci(a,b);//init generator 
      var fiNums = [];//init result array 
      for (var i = 0; i < n; i++) { 
       var tmp=fi.next();//{value:1, done:false} 
       fiNums.push(tmp.value); 
      } 
      //output result 
      document.getElementById('output').innerHTML = fiNums.join(', '); 
     } 

//get all series in once 
function getNumbersOld(){ 
    var a = document.getElementById('cur').value-0; 
    var b = document.getElementById('nxt').value-0; 
    var n = document.getElementById('cnt').value-0; 
    var fiNums = [b,a]; 
    for (var i = 2; i < n; i++) { 
     fiNums.unshift(fiNums[0]+fiNums[1]); 
    } 
    document.getElementById('output').innerHTML = fiNums.reverse().join(', '); 
} 
    </script> 
</head> 
<body> 
Generate Fibonacci series <br /> 
Current:<input type="number" id="cur" value="1" /> 
    Next:<input type="number" id="nxt" value="1" /> 
    Count:<input type="number" id="cnt" value="5" /> 
    <button onclick="getNumbersOld()">Get Numbers</button> 
    <div id="output"></div> 
</body> 
</html> 
+1

あなたの実装は不必要に過度に複雑です。私はいつでもループ上の再帰を好む。あなたが1行でやり遂げることができれば。次に、それを1行で実行してください – Dummy

+0

更新を参照してください。これがあなたが望むものであることを願っています。 –

0

グローバル変数に関する回答と、他の人からの各再帰呼び出しの結果をどのように出力しなかったかに基づいて、私は問題に最終的に正しい解決策を得ることができました。

function fibanocci(prev, next, n) { 
    /* 
     n - 2 is here so it will print the first n numbers in the Fibonacci sequence 
     instead of n + 2 numbers because we have to account for the 2 initial numbers, 
     1 and 2 in this case, and I don't want the client to account for these 2 initial 
     numbers themselves. Math.abs(n-2) so the recursion will stop when n is 1 so the 
     call stack will not get bloated and throw an exception. 
    */ 
    return n > Math.abs(n-2) ? prev + "," + fibanocci(Math.max(prev,next), prev + next, --n) : prev; 
} 

document.querySelector('button').addEventListener('click', function() { 
    console.log(fibonacci(1, 2, 5)); 
}); 
関連する問題