Swiftデータ構造-2 D配列Array 2 D

2935 ワード

声明:アルゴリズムとデータ構造の文章はすべて作者がgithubから翻訳して、みんなが読むのを便利にします.英語の読解力の強い友达は、swiftアルゴリズムクラブに直接行ってすべての原文を見て、迅速に勉強することができます.作者は同時に学習の中で、交流を歓迎します
CとObjective-Cでは、9 x 7のグリッドの組合せを宣言するコードを書きます.int cookies[9][7];
このコードは63要素を含む2ビット配列を作成します.3列6行目のグリッドを見つけるには、次の方法を使用します.myCookie = cookies[3][6];
一方,swiftでは,このように多次元配列を作成する表現は許されない.swiftで多次元配列を作成する場合は、次の手順に従います.
var cookies = [[Int]]()
for _ in 1...9 {
  var row = [Int]()
  for _ in 1...7 {
    row.append(0)
  }
  cookies.append(row)
}

次に、3列6行目のグリッドを見つけるには、次のようにします.let myCookie = cookies[3][6]
配列を1行のコードで作成することもできます.var cookies = [[Int]](repeating: [Int](repeating: 0, count: 7), count: 9)
ここでは関数全体が少し複雑に見えるかもしれませんが、補助関数を使用して簡略化することができます.
func dim(_ count: Int, _ value: T) -> [T] {
  return [T](repeating: value, count: count)
}

簡略化後の効果は次のとおりです.var cookies = dim(9, dim(7, 0))
ここでswiftは配列のデータ型をintと推定する.なぜなら,我々の初期値は0に設定されているからである.データ型を変更する場合は、宣言で直接変更できます.var cookies = dim(9, dim(7, "yum"))
ここでのdim()関数は、3 Dなどの多次元の配列を自由に作成することができます.var threeDimensions = dim(2, dim(3, dim(4, 0)))
しかし、このような作成方法には、各次元がどのような情報を表しているか分からないという明らかな欠点があります.だから、私たちは自分で自分のタイプを創造して同じ効果を達成することができて、同時に更に簡単で実用的です.
public struct Array2D {
  public let columns: Int
  public let rows: Int
  fileprivate var array: [T]
  
  public init(columns: Int, rows: Int, initialValue: T) {
    self.columns = columns
    self.rows = rows
    array = .init(repeating: initialValue, count: rows*columns)
  }
  
  public subscript(column: Int, row: Int) -> T {
    get {
      precondition(column < columns, "Column \(column) Index is out of range. Array(columns: \(columns), rows:\(rows))")
      precondition(row < rows, "Row \(row) Index is out of range. Array(columns: \(columns), rows:\(rows))")
      return array[row*columns + column]
    }
    set {
      precondition(column < columns, "Column \(column) Index is out of range. Array(columns: \(columns), rows:\(rows))")
      precondition(row < rows, "Row \(row) Index is out of range. Array(columns: \(columns), rows:\(rows))")
      array[row*columns + column] = newValue
    }
  }
}
Array2Dは、数値だけでなく任意のタイプのオブジェクトを持つことができる通クラスです.Array2Dインスタンスは、次の方法で作成できます.var cookies = Array2D(columns: 9, rows: 7, initialValue: 0) subscript関数を使用すると、配列内の指定されたオブジェクトを次の方法で取得できます.let myCookie = cookies[column, row]
または配列内のオブジェクトを変更します.cookies[column, row] = newCookie
原理的には、Array2Dは、1次元の配列でデータを格納する.特定のオブジェクトのインデックスは(row x numberOfColumns) + columnで換算されますが、使用者にとっては、ここの行と列を考慮すればよいので、残りの作業はArray2Dに任せて完了します.これも元のデータをクラスや構造体にパッケージする利点です.