Swift教室 Swift と競技プログラミングの教室

ループの設計

読了目安 約3分

ループを 1 回分から組み立てる 3 手順と、集計・探索・最大値の頻出パターン。

この章の目次

ループを使う処理は、最初から完成形を書こうとするとつまずきます。 「1 回分」から組み立てる手順の型を覚えると、迷わず書けるようになります。

ループを書く 3 手順

  1. やりたい処理を 1 回分だけ書く
  2. それを繰り返しにする
  3. 回ごとに変わる部分を、カウンタや結果をためる変数に置き換える

「N 個の整数の合計」を例に、この手順で書いてみます。

手順 1 では、0 番目の要素を合計に足す処理を 1 回分だけ書きます。

Swift
sum += a[0]

手順 2 と 3 では、これを for で囲み、回ごとに変わる 0 をカウンタ i に置き換えます。

Swift
for i in 0..<n {
    sum += a[i]
}

入力と組み合わせた完成形です。 入力の読み方は 入力と実行順序 の定型句です。

Swift
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 5

sum のように結果をためていく変数を累積変数と呼びます。 ループの前に初期値 0 を入れておくのを忘れないでください。 この「集計」が、ループの 1 つ目の頻出パターンです。

試してみよう: sum += a[i]sum += 1 に変えると何が出力されるか、予想してから実行してください。

探索 — 見つけたら break

2 つ目のパターンは、目当ての値があるか調べる「探索」です。 見つけたことを覚えておく Bool の変数をフラグと呼びます。

Swift
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 つ目のパターンは、「これまでの最大値」を持ち歩いて更新していく形です。

Swift
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() が使えます。

Swift
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 23 3 の 2 か所です。

制約: 2 ≤ N ≤ 100、値は 1 以上 100 以下

テキスト
入力例:
5
1 2 2 3 3

出力例:
2
模範解答
Swift
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)