指定された数値までの合計を求める
重要度: 5
num 1 + 2 + ... + n
の合計を計算する関数sumTo(n)
を作成。
たとえば
sumTo(1) = 1
sumTo(2) = 2 + 1 = 3
sumTo(3) = 3 + 2 + 1 = 6
sumTo(4) = 4 + 3 + 2 + 1 = 10
...
sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050
3通りの解法を用意。
- forループを使用して
- 再帰を使用して、
n > 1
の場合、sumTo(n) = n + sumTo(n-1)
となるため。 - 等差数列の公式を使用して。
結果の例
function sumTo(n) { /*... your code ... */ }
alert( sumTo(100) ); // 5050
追伸: どの解法が最も速く、どの解法が最も遅いでしょうか? その理由を教えてください。
追伸2: 再帰を使用してsumTo(100000)
をカウントできますか?
ループを使用した解
function sumTo(n) {
let sum = 0;
for (let i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
alert( sumTo(100) );
再帰を使用した解
function sumTo(n) {
if (n == 1) return 1;
return n + sumTo(n - 1);
}
alert( sumTo(100) );
以下の数式を使用した解: sumTo(n) = n*(n+1)/2
function sumTo(n) {
return n * (n + 1) / 2;
}
alert( sumTo(100) );
追伸: もちろん、公式が最速の解です。どの数値n
に対しても、たった3つの操作を使用しています。数学が役に立ちます!
ループを使用した解が速度において2番目です。再帰とループのどちらの場合も、同じ数値を合計します。ただし、再帰にはネストされた呼び出しと実行スタックの管理が含まれます。それは、リソースを消費するため、より遅くなります。
追伸2: 一部のエンジンは「テイルコール」最適化をサポートします。再帰呼び出しが関数の最後で実行され、他の計算が実行されない場合、外部関数は実行を再開する必要がないため、エンジンは実行コンテキストを記憶する必要がありません。これにより、メモリに対する負荷が軽減されます。ただし、JavaScriptエンジンがテイルコール最適化をサポートしていない場合(ほとんどがサポートしていません)、エラーが発生します: スタックの最大サイズを超えました。通常、スタックの全サイズには制限があるためです。