ループの設計
読了目安 約3分
ループを 1 回分から組み立てる 3 手順と、集計・探索・最大値の頻出パターン。
この章の目次
ループを使う処理は、最初から完成形を書こうとするとつまずきます。 「1 回分」から組み立てる手順の型を覚えると、迷わず書けるようになります。
ループを書く 3 手順
- やりたい処理を 1 回分だけ書く
- それを繰り返しにする
- 回ごとに変わる部分を、カウンタや結果をためる変数に置き換える
「N 個の整数の合計」を例に、この手順で書いてみます。
手順 1 では、0 番目の要素を合計に足す処理を 1 回分だけ書きます。
sum += a[0]手順 2 と 3 では、これを for で囲み、回ごとに変わる 0 をカウンタ i に置き換えます。
for i in 0..<n {
sum += a[i]
}入力と組み合わせた完成形です。 入力の読み方は 入力と実行順序 の定型句です。
let n = Int(readLine()!)!
let a = readLine()!.split(separator: " ").map { Int($0)! }
var sum = 0
for i in 0..<n {
sum += a[i]
}
print(sum)5
3 1 4 1 5sum のように結果をためていく変数を累積変数と呼びます。
ループの前に初期値 0 を入れておくのを忘れないでください。
この「集計」が、ループの 1 つ目の頻出パターンです。
試してみよう: sum += a[i] を sum += 1 に変えると何が出力されるか、予想してから実行してください。
探索 — 見つけたら break
2 つ目のパターンは、目当ての値があるか調べる「探索」です。 見つけたことを覚えておく Bool の変数をフラグと呼びます。
let target = 50
let a = [31, 41, 59, 26, 50, 58]
var found = false
for x in a {
if x == target {
found = true
break
}
}
if found {
print("\(target) が見つかりました")
} else {
print("\(target) は見つかりませんでした")
}見つけた瞬間に break で抜ければ、残りを調べる無駄がありません。
最大値の更新
3 つ目のパターンは、「これまでの最大値」を持ち歩いて更新していく形です。
let a = [31, 41, 59, 26, 50, 58]
var maxValue = a[0]
for x in a {
if x > maxValue {
maxValue = x
}
}
print(maxValue)初期値は a[0] にします。
0 を初期値にすると、要素がすべて負のときに間違った答えになります。
添字と要素を同時に使う
要素だけでよければ for x in a、添字が必要なら for i in 0..<a.count と書き分けます。
両方欲しいときは enumerated() が使えます。
let a = [31, 41, 59]
for (i, x) in a.enumerated() {
print("\(i) 番目は \(x)")
}学びどころ
| 概念 | 一言まとめ |
|---|---|
| 3 手順 | 1 回分 → 繰り返し → 変わる部分を変数に |
| 集計 | 累積変数に初期値を入れてためる |
| 探索 | フラグを立てて break で抜ける |
| 最大値 | 初期値は a[0]。0 は負の値で事故る |
enumerated() | 添字と要素のペアを取り出す |
演習
1 行目に整数 N、2 行目に N 個の整数が空白区切りで入力されます。 隣り合う 2 つの値が等しい場所が何か所あるかを出力してください。
入力例では 2 2 と 3 3 の 2 か所です。
制約: 2 ≤ N ≤ 100、値は 1 以上 100 以下
入力例:
5
1 2 2 3 3
出力例:
2模範解答
let n = Int(readLine()!)!
let a = readLine()!.split(separator: " ").map { Int($0)! }
var count = 0
for i in 0..<n - 1 {
if a[i] == a[i + 1] {
count += 1
}
}
print(count)