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

多次元配列

読了目安 約2分

配列の配列でグリッドを表す。定石の作り方と、グリッド入力の読み方。

この章の目次

マス目 (グリッド) や表の形のデータは、「配列の配列」で表せます。

配列の配列

[[Int]] は、整数の配列を要素に持つ配列の型です。 table[i][j] で i 行目の j 列目を取り出します (どちらも 0 始まり)。

Swift
let table = [
    [1, 2, 3],
    [4, 5, 6],
]
print(table[0][2])
print(table[1][0])

大きさを決めて作る定石

H 行 W 列をすべて 0 で作るには、Array(repeating:count:) を 2 重にします。

Swift
let h = 2
let w = 3
var grid = Array(repeating: Array(repeating: 0, count: w), count: h)
grid[0][0] = 1
grid[1][2] = 9
print(grid)

内側の Array(repeating: 0, count: w) が 1 行分で、それを h 個並べています。 grid[行][列] の順で使えるように、列数の w が内側です。

試してみよう: hw の値を入れ替えて、出力の形がどう変わるか確かめてください。

グリッドの入力

「1 行目に H と W、続く H 行に各行の値」という入力形式が定番です。 1 行ずつ読んで詰めたら、2 重ループで全マスを走査します。

Swift
let hw = readLine()!.split(separator: " ").map { Int($0)! }
let h = hw[0]
let w = hw[1]
var grid = Array(repeating: Array(repeating: 0, count: w), count: h)
for i in 0..<h {
    let row = readLine()!.split(separator: " ").map { Int($0)! }
    for j in 0..<w {
        grid[i][j] = row[j]
    }
}
var total = 0
for i in 0..<h {
    for j in 0..<w {
        total += grid[i][j]
    }
}
print(total)
入力例
2 3
1 2 3
4 5 6

外側の i が行、内側の j が列です。

文字のグリッド

ox が並ぶマス目は、読んだ文字列を Array(...) で文字の配列にすると添字で扱えます。

Swift
let row = Array("-xo")
print(row[2])
print(row.count)

学びどころ

概念一言まとめ
[[Int]]配列の配列。a[行][列] で 1 マス
作る定石Array(repeating: Array(repeating: 0, count: W), count: H)
走査外側が行、内側が列の 2 重ループ
文字のグリッドArray(文字列) で文字の配列にする

演習

N 人でゲームの総当たり戦をしました。 N 行 N 列の勝敗表について、i 行目の j 文字目は、人 i が人 j に勝ったなら o、負けたなら x です。 自分自身との対戦にあたる場所は - です。

各人の勝ち数を、人 1 から順に 1 行ずつ出力してください。 スターターの grid には、勝敗表が文字の配列の配列として読み込んであります。

制約: 2 ≤ N ≤ 10

テキスト
入力例:
3
-xo
o-x
xo-

出力例:
1
1
1
模範解答
Swift
let n = Int(readLine()!)!
let grid = (0..<n).map { _ in Array(readLine()!) }
for i in 0..<n {
    var wins = 0
    for j in 0..<n {
        if grid[i][j] == "o" {
            wins += 1
        }
    }
    print(wins)
}