1 から N までの合計
毎回 0 に戻ってしまう
繰り返しの結果を 1 つの値にまとめたいときは、途中経過を貯めておく変数を用意します。この変数を置く場所を 1 行間違えると、答えは必ず最後の 1 周ぶんだけになります。
1 から 20 までのうち、4 で割り切れる数が何個あるかを数える例で見てみます。
Java
int count = 0;
for (int i = 1; i <= 20; i++) {
if (i % 4 == 0) {
count++;
}
}
// count は 5int count = 0; が for の 外 にあることが要です。これを中括弧の内側に書くと、こうなります。
Java
for (int i = 1; i <= 20; i++) {
int count = 0; // 毎周ここで作り直される
if (i % 4 == 0) {
count++;
}
}
// ここでは count が見えない1 周ごとに宣言し直されて 0 に戻るので、count は多くても 1 にしかなりません。しかも中括弧の中で宣言した変数はループを抜けると消えるため、最後に読むこともできません。
貯める変数は、ループの外で用意し、ループの中で書き換え、ループを抜けてから読みます。この 3 つが別々の行にある形が、繰り返しで集計するときの基本の形です。
| 周 | i | i % 4 | 周の終わりの count |
|---|---|---|---|
| 3 | 3 | 3 | 0 |
| 4 | 4 | 0 | 1 |
| 5 | 5 | 1 | 1 |
| 8 | 8 | 0 | 2 |
count は毎周ゼロから作り直されるのではなく、前の周の値の上に積み上がっています。count++ は count = count + 1 の短い書き方で、右側の count が前の周までの値です。1 以外を足したいときは次のように書きます。
Java
count += 3; // count = count + 3 と同じ1 周も回らないときは、初期値がそのまま残る
for は、最初に条件を確かめてから本体に入ります。条件が最初から成立しなければ、本体は 1 度も動きません。
そのとき貯める変数は用意したときの値のまま残り、それがそのまま答えになります。だから初期値は「まだ何も起きていないときの答え」として正しい値を選びます。個数を数えるなら 0、掛け合わせていくなら 1 です。
大きな数を扱うときは
intの上限に注意してください。約 21 億を超えると符号が反転してマイナスになります。桁が伸びそうならlongを使います。
やってみよう
sumOneToN(int n) を完成させて、1 + 2 + ... + n の合計を返してください。
forの外に、合計を貯める変数を用意する- ループの中で、その変数に
iを足し込む - ループを抜けてから、その変数を返す
- 実行して
10110005の 5 件を通す
n 自身も足す必要があるので、条件を i < n にすると答えが n だけ足りません。sumOneToN(10) が 55 ではなく 45 になったら、まずそこを疑ってください。n が 0 のケースは、初期値を正しく選んでいれば何も足さなくても通ります。
要件
- クラス名は
Solution、メソッド名はsumOneToN、引数はint nひとつにすること - メソッドの戻り値の型は
intで、1 + 2 + ... + nの合計を返すこと nが0のときは0を返すこと (ループが 1 周も回らないケースに対応)
入出力例
sumOneToN(10) → 55
sumOneToN(1) → 1
sumOneToN(100) → 5050
sumOneToN(0) → 0
sumOneToN(5) → 15