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

for-in 文と break・continue

読了目安 約3分

決まった回数の繰り返しは for-in 文で書く。範囲演算子と break・continue、stride を学ぶ。

この章の目次

回数が先に決まっている繰り返しは、while 文より短く書けます。 それが for-in 文です。

for-in 文

for-in 文は、値の並びから 1 つずつ取り出してブロックを実行します。

Swift
for i in 1...5 {
    print(i)
}

i に 1 から 5 が順に入り、5 回繰り返します。 while 文と違い、カウンタの宣言も更新も書きません。 i は書き換えられない定数です。

取り出した値を使わないときは、名前の代わりに _ を書きます。

Swift
for _ in 1...3 {
    print("ピザ")
}

2 つの範囲演算子

1...5 のように値の並びを作る演算子を範囲演算子と呼びます。

書き方意味含まれる値
1...51 以上 5 以下1, 2, 3, 4, 5
0..<50 以上 5 未満0, 1, 2, 3, 4

..< は終わりの値を含みません。 0 始まりで N 回繰り返すときは 0..<n が便利です。

1...n は、n が 0 だと実行時エラーになります。 下限が上限より大きい範囲は作れないためです。0 回になりうる繰り返しには 0..<n を使ってください。

break と continue

break は繰り返しをその場で打ち切ります。 continue は今の回の残りを飛ばして、次の回へ進みます。

Swift
for i in 1...10 {
    if i % 3 == 0 {
        continue
    }
    if i > 7 {
        break
    }
    print(i)
}

3 の倍数は continue で飛ばされ、8 に達した時点で break が繰り返し全体を終えます。 どちらも while 文の中でも使えます。

stride で逆順と飛ばし

stride(from:to:by:) は、始点から終点の手前まで、指定した幅で進む並びを作ります。

Swift
for i in stride(from: 10, to: 0, by: -2) {
    print(i)
}

10 から 2 ずつ減り、0 の手前の 2 で終わります。 by を負にすると逆順、2 以上にすると飛ばしになります。

試してみよう: to: 0to: -1 に変えて、0 が出力されるようになることを確かめてください。

while との使い分け

  • 回数や範囲が先に決まっている: for-in 文
  • 終わる条件しか決まっていない: while 文

「N 行の入力を読む」は前者の代表です。

Swift
let n = Int(readLine()!)!
var sum = 0
for _ in 1...n {
    sum += Int(readLine()!)!
}
print(sum)
入力例
3
10
20
5

学びどころ

概念一言まとめ
for-in 文並びから 1 つずつ取り出して繰り返す
1...n / 0..<n終わりを含む範囲と含まない範囲
break / continue全体を打ち切る / 今の回だけ飛ばす
stride(from:to:by:)逆順や飛ばしの並びを作る

演習

1 行目に操作の回数 N が入力されます。 続く N 行に「op X」の形の操作が並びます。

op は + - * / のどれか、X は整数です。 電卓の値は 0 から始まります。 操作を上から順に適用し、そのたびに値を 1 行で出力してください。

割り算は整数の割り算で、負の数は 0 に近づく向きに切り捨てます (-7 / 2 は -3)。

制約: 1 ≤ N ≤ 100。-100 ≤ X ≤ 100。op が / のとき X は 0 ではありません。

テキスト
入力例:
4
+ 5
* 3
- 2
/ 4

出力例:
5
15
13
3

ヒント: let parts = readLine()!.split(separator: " ") と分解すると、parts[0] が op、Int(parts[1])! が X です。

模範解答

op は数値ではないので、5 章の定型句から map を外して使います。

Swift
let n = Int(readLine()!)!
var value = 0
for _ in 1...n {
    let parts = readLine()!.split(separator: " ")
    let op = parts[0]
    let x = Int(parts[1])!
    if op == "+" {
        value += x
    } else if op == "-" {
        value -= x
    } else if op == "*" {
        value *= x
    } else {
        value /= x
    }
    print(value)
}