[Swift]多维数组的表示和存储:N维数组映射到一维数组(一一对应)!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
?微信公眾號(hào):山青詠芝(shanqingyongzhi)
?博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/?)
?GitHub地址:https://github.com/strengthen/LeetCode
?原文地址:https://www.cnblogs.com/strengthen/p/9844577.html?
?如果鏈接不是山青詠芝的博客園地址,則可能是爬取作者的文章。
?原文已修改更新!強(qiáng)烈建議點(diǎn)擊原文地址閱讀!支持作者!支持原創(chuàng)!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
數(shù)組:有序的元素序列。 若將有限個(gè)類(lèi)型相同的變量的集合命名,那么這個(gè)名稱(chēng)為數(shù)組名。組成數(shù)組的各個(gè)變量稱(chēng)為數(shù)組的分量,也稱(chēng)為數(shù)組的元素,有時(shí)也稱(chēng)為下標(biāo)變量。用于區(qū)分?jǐn)?shù)組的各個(gè)元素的數(shù)字編號(hào)稱(chēng)為下標(biāo)。數(shù)組是在程序設(shè)計(jì)中,為了處理方便, 把具有相同類(lèi)型的若干元素按無(wú)序的形式組織起來(lái)的一種形式。這些無(wú)序排列的同類(lèi)數(shù)據(jù)元素的集合稱(chēng)為數(shù)組。數(shù)組是用于儲(chǔ)存多個(gè)相同類(lèi)型數(shù)據(jù)的集合。
二維數(shù)組:本質(zhì)上是以數(shù)組作為數(shù)組元素的數(shù)組,即“數(shù)組的數(shù)組”。二維數(shù)組又稱(chēng)為矩陣,行列數(shù)相等的矩陣稱(chēng)為方陣。
對(duì)稱(chēng)矩陣:a[i][j] = a[j][i]
對(duì)角矩陣:n階方陣主對(duì)角線外都是零元素
三維數(shù)組:指維數(shù)為三的數(shù)組結(jié)構(gòu)。三維數(shù)組是最常見(jiàn)的多維數(shù)組,由于其可以用來(lái)描述三維空間中的位置或狀態(tài)而被廣泛使用。
定義二維數(shù)組
1 //方式1 2 var arr1 = [[Int]]() 3 print(arr1) 4 //Print [] 5 6 //方式2 7 var arr2 = Array<Array<Int>>() 8 print(arr2) 9 //Print [] 10 11 //方式3:定義3列4行的二維數(shù)組,元素初始化為0 12 var arr3 = [[Int]](repeating: [Int](repeating: 0, count: 3), count: 4) 13 print(arr3) 14 //Print [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]二維數(shù)組的遍歷
1 //遍歷行 2 for row in arr3 3 { 4 print(row) 5 //Print [0, 0, 0] 6 //遍歷列 7 for col in row 8 { 9 //從左到右,從上到下進(jìn)行遍歷 10 print(col) 11 //Print 0 12 } 13 }定義三維數(shù)組
1 //方式1 2 var arr1 = [[[Int]]]() 3 print(arr1) 4 //Print [] 5 6 //方式2 7 var arr2 = Array<Array<Array<Int>>>() 8 print(arr2) 9 //Print [] 10 11 //方式3:定義三維數(shù)組,元素初始化為0,由內(nèi)往外 12 var arr3 = [[[Int]]](repeating: [[Int]](repeating: [Int](repeating: 0, count: 2), count: 3), count: 4) 13 print(arr3) 14 //2個(gè)元素的一維數(shù)組,3個(gè)元素的二維數(shù)組,4個(gè)元素的三位數(shù)組 15 /* 16 [ 17 [ 18 [0, 0], [0, 0], [0, 0] 19 ], 20 [ 21 [0, 0], [0, 0], [0, 0] 22 ], 23 [ 24 [0, 0], [0, 0], [0, 0] 25 ], 26 [ 27 [0, 0], [0, 0], [0, 0] 28 ] 29 ] 30 */三維數(shù)組的遍歷
1 //遍歷高h(yuǎn)eight 2 for height in arr3 3 { 4 print(height) 5 //Print [[0, 0], [0, 0], [0, 0]] 6 //遍歷長(zhǎng)depth 7 for depth in height 8 { 9 print(depth) 10 //Print [0, 0] 11 //遍歷寬width 12 for width in depth 13 { 14 print(width) 15 //Print 0 16 } 17 } 18 }使用函數(shù)來(lái)創(chuàng)建多維數(shù)組
1 //num:元素個(gè)數(shù) 2 //value:元素初始值 3 func dimension<T>(_ num: Int, _ value: T) -> [T] { 4 return [T](repeating: value, count: num) 5 }示例代碼:
1 //用嵌套的方式創(chuàng)建多維數(shù)組 2 //創(chuàng)建一維數(shù)組 3 let arr1 = dimension(1,0) 4 print(arr1) 5 //Print [0] 6 7 //創(chuàng)建二維數(shù)組 8 let arr2 = dimension(2,arr1) 9 //即:let arr2 = dimension(2,dimension(1,0)) 10 print(arr2) 11 //Print [[0], [0]] 12 13 //創(chuàng)建三維數(shù)組 14 let arr3 = dimension(3,arr2) 15 //即:let arr3 = dimension(3,dimension(2,dimension(1,0))) 16 print(arr3) 17 //Print [[[0], [0]], [[0], [0]], [[0], [0]]] 18 19 //創(chuàng)建四維數(shù)組 20 let arr4 = dimension(4,arr3) 21 //即:let arr4 = dimension(4,dimension(3,dimension(2,dimension(1,0)))) 22 print(arr4) 23 //Print [[[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]]] 24 25 //創(chuàng)建五維數(shù)組 26 let arr5 = dimension(5,arr4) 27 //即:arr5 = dimension(5,dimension(4,dimension(3,dimension(2,dimension(1,0))))) 28 print(arr5) 29 //Print [[[[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]]], [[[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]]], [[[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]]], [[[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]]], [[[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]], [[[0], [0]], [[0], [0]], [[0], [0]]]]] 30 31 //......使用函數(shù)嵌套的方法創(chuàng)建多維數(shù)組有一個(gè)很大的缺陷:無(wú)法明確維度所代表的意義。
所以,可以考慮使用一維數(shù)組存儲(chǔ)多維數(shù)組的數(shù)據(jù)。
創(chuàng)建一個(gè)Array2D類(lèi),用一維數(shù)組存儲(chǔ)二維數(shù)組的數(shù)據(jù)。
此時(shí)我們只需關(guān)注“列”和“行”的數(shù)值,細(xì)節(jié)交由Array2D來(lái)處理,這就是將原始數(shù)據(jù)類(lèi)型包裝成包裝器類(lèi)型或結(jié)構(gòu)體的優(yōu)點(diǎn)。
二維數(shù)組A[rows][columns]放到一維數(shù)組B中的對(duì)應(yīng)公式:
兩種方式 :
(1)、按行遍歷?
A[i][j] = B[ i + j * rows ]
(2)、按列遍歷
A[i][j] = B[ i * columns + j ]
1 public struct Array2D<T> { 2 //列數(shù) 3 public let columns:Int 4 //行數(shù) 5 public let rows:Int 6 fileprivate var array: [T] 7 8 //初始化 9 public init(columns: Int, rows: Int, initialValue: T) { 10 self.columns = columns 11 self.rows = rows 12 array = .init(repeating: initialValue, count: rows*columns) 13 } 14 15 //subscript函數(shù)可以檢索數(shù)組中的值 16 public subscript(column: Int, row: Int) -> T { 17 //讀取 18 get { 19 //先決條件 20 precondition(column <= columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))") 21 precondition(row <= rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))") 22 return array[row * columns + column] 23 //或 return array[row + column * rows] 24 } 25 //寫(xiě)入 26 set { 27 //先決條件 28 precondition(column <= columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))") 29 precondition(row <= rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))") 30 array[row * columns + column] = newValue 31 //或 array[row + column * rows] = newValue 32 } 33 } 34 }示例代碼:
1 // 創(chuàng)建一個(gè)二維數(shù)組的實(shí)例 2 var arr2D = Array2D(columns: 2, rows:3, initialValue: 0) 3 print(arr2D) 4 //Print Array2D<Int>(columns: 2, rows: 3, array: [0, 0, 0, 0, 0, 0]) 5 6 //subscript函數(shù)可以檢索數(shù)組中的元素值 7 let num = arr2D[1, 1] 8 print(num) 9 //Print 0 10 11 //給數(shù)組中的元素賦值 12 arr2D[1, 1] = 88 13 print(arr2D[1, 1]) 14 //Print 88創(chuàng)建一個(gè)Array3D類(lèi),用一維數(shù)組存儲(chǔ)三維維數(shù)組的數(shù)據(jù)。
此時(shí)我們只需關(guān)注“長(zhǎng)”、“寬”和“高”的數(shù)值,細(xì)節(jié)交由Array3D來(lái)處理,這就是將原始數(shù)據(jù)類(lèi)型包裝成包裝器類(lèi)型或結(jié)構(gòu)體的優(yōu)點(diǎn)。
三維數(shù)組A[widths][depths][heights]放到一維數(shù)組B中的對(duì)應(yīng)公式:
A[i][j][k] = B[ ( i - 1 ) * ( depths * heights ) + ( j - 1 ) * heights + k ]
示例代碼:
1 // 創(chuàng)建一個(gè)三維數(shù)組的實(shí)例 2 var arr3D = Array3D(widths: 2, depths: 3, heights: 4, initialValue: 0) 3 print(arr3D) 4 //Print Array3D<Int>(widths: 2, depths: 3, heights: 4, array: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) 5 6 //subscript函數(shù)可以檢索數(shù)組中的元素值 7 let num = arr3D[1, 1, 1] 8 print(num) 9 //Print 0 10 11 //給數(shù)組中的元素賦值 12 arr3D[1, 1, 1] = 88 13 print(arr3D[1, 1, 1]) 14 //Print 88四維維數(shù)組A[a][b][c][d]放到一維數(shù)組B中的對(duì)應(yīng)公式:
A[i][j][k][w] = B[(i - 1) * (b * c * d) + (j - 1) * (c * d) + (k - 1) * d + w]
歸納演繹......
N維數(shù)組映射到一維數(shù)組
由此及彼,由表及里,歸納總結(jié),創(chuàng)建一個(gè)Dim類(lèi),用一維數(shù)組存儲(chǔ)n維數(shù)組的數(shù)據(jù),
此時(shí)我們只需關(guān)注每一個(gè)維度的數(shù)值,細(xì)節(jié)交由Dim來(lái)處理,這就是將原始數(shù)據(jù)類(lèi)型包裝成包裝器類(lèi)型或結(jié)構(gòu)體的優(yōu)點(diǎn)。
深入思考:
(1)、多維度中各維度所表示意義的順序可以任意確定,確定維度順序之后,就按照既定的維度順序進(jìn)行對(duì)一維數(shù)組進(jìn)行讀寫(xiě)。
(2)、如同二維數(shù)組中可以按照行遍歷或者按照列遍歷一樣。多維數(shù)組也可以任意確定多維數(shù)組中下標(biāo)i、j、k、w、...的順序。
下標(biāo)順序確定之后就不可變更,根據(jù)下標(biāo)順序得出對(duì)應(yīng)公式,公式從上文中請(qǐng)歸納,就按照既定的下標(biāo)順序進(jìn)行對(duì)一維數(shù)組進(jìn)行讀寫(xiě)。
1 public struct Dim<T> { 2 //用一個(gè)數(shù)組來(lái)接收維度信息 3 //元素個(gè)數(shù)為維度 4 //元素?cái)?shù)值為對(duì)應(yīng)維度的具體數(shù)量 5 public let dimension:[Int] 6 fileprivate var array:[T] 7 //只能初始化一次 8 public let product:Int 9 //數(shù)組信息 10 public let arrayInfo:String 11 12 //初始化 13 public init(dimension:[Int], initialValue: T) { 14 self.dimension = dimension 15 //數(shù)組各元素求積reduce(1) 16 //用于一維數(shù)組保存多維數(shù)組的信息 17 self.product = dimension.reduce(1) {$0 * $1} 18 //初始化數(shù)組 19 array = .init(repeating: initialValue, count: product) 20 //初始化維度信息 21 var str:String = " Array<T>(" 22 for i in 0...(dimension.count - 1) 23 { 24 str += String(i + 1) + "Dimension: \(dimension[i])," 25 } 26 //刪除最后一個(gè)字符串‘,’ 27 str.remove(at: str.index(before: str.endIndex)) 28 str += ")" 29 arrayInfo = str 30 } 31 32 //subscript函數(shù)可以檢索數(shù)組中的值 33 //T?:讀取時(shí)如果輸入的維度不等于原維度則返回nil 34 //取值需使用強(qiáng)制解包 35 public subscript(_ numbers: Int...) -> T? { 36 //讀取 37 get 38 { 39 //判斷元素個(gè)數(shù)是否等于維度數(shù)組個(gè)數(shù) 40 if numbers.count == dimension.count 41 { 42 for i in 0...(dimension.count - 1) 43 { 44 //先決條件 45 precondition( numbers[i] <= dimension[i], "\(String(i + 1))Dimension:\(numbers[i]) Index is out of range. " + arrayInfo) 46 } 47 return array[getIndex(numbers)] 48 } 49 return nil 50 } 51 52 //寫(xiě)入 53 set 54 { 55 //判斷元素個(gè)數(shù)是否等于維度數(shù)組個(gè)數(shù) 56 if numbers.count == dimension.count 57 { 58 for i in 0...(dimension.count - 1) 59 { 60 //先決條件 61 precondition( numbers[i] <= dimension[i], "\(String(i + 1))Dimension:\(numbers[i]) Index is out of range. " + arrayInfo) 62 } 63 array[getIndex(numbers)] = newValue! 64 } 65 } 66 67 } 68 //求解多維數(shù)組的元素在一維數(shù)組中的索引 69 private func getIndex(_ dim: [Int]) -> Int 70 { 71 var sum:Int = 0 72 for index in 0...(dim.count - 1) 73 { 74 sum += (dim[index] - 1) * getProduct(index) 75 } 76 return sum 77 } 78 //求部分元素的積 79 private func getProduct(_ index:Int) -> Int 80 { 81 //數(shù)組各元素求積 82 var accumulate:Int = 1 83 //加1 84 var front:Int = index + 1 85 let real:Int = dimension.count - 1 86 if real > front 87 { 88 let arr:[Int] = [Int](dimension[front...real]) 89 if arr.count != 0 90 { 91 //數(shù)組各元素求積reduce(1) 92 accumulate = arr.reduce(1){$0 * $1} 93 } 94 } 95 return accumulate 96 } 97 }Dim類(lèi),用一維數(shù)組存儲(chǔ)n維數(shù)組的數(shù)據(jù),示例:
1 // 創(chuàng)建一維數(shù)組的實(shí)例 2 var arr1 = Dim(dimension:[3], initialValue: 1) 3 print(arr1) 4 //Print Dim<Int>(dimension: [3], array: [1, 1, 1], product: 3, arrayInfo: " Array<T>(1Dimension: 3)") 5 // 創(chuàng)建二維數(shù)組的實(shí)例 6 var arr2 = Dim(dimension:[1,2], initialValue: 2) 7 print(arr2) 8 //Print Dim<Int>(dimension: [1, 2], array: [2, 2], product: 2, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2)") 9 // 創(chuàng)建三維數(shù)組的實(shí)例 10 var arr3 = Dim(dimension:[1,2,3], initialValue: 3) 11 print(arr3) 12 //Print Dim<Int>(dimension: [1, 2, 3], array: [3, 3, 3, 3, 3, 3], product: 6, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2,3Dimension: 3)") 13 // 創(chuàng)建四維數(shù)組的實(shí)例 14 var arr4 = Dim(dimension:[1,2,3,4], initialValue: 4) 15 print(arr4) 16 //Print Dim<Int>(dimension: [1, 2, 3, 4], array: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], product: 24, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2,3Dimension: 3,4Dimension: 4)") 17 // 創(chuàng)建五維數(shù)組的實(shí)例 18 var arr5 = Dim(dimension:[1,2,3,4,5], initialValue: 5) 19 print(arr5) 20 //Print Dim<Int>(dimension: [1, 2, 3, 4, 5], array: [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], product: 120, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2,3Dimension: 3,4Dimension: 4,5Dimension: 5)") 21 //...... 22 23 //subscript函數(shù)可以檢索數(shù)組中的元素值,Optional為可選類(lèi)型 24 //一維數(shù)組 25 arr1[2] = 11 26 print(arr1) 27 //Print Dim<Int>(dimension: [3], array: [1, 11, 1], product: 3, arrayInfo: " Array<T>(1Dimension: 3)") 28 let num1 = arr1[1] 29 print(num1) 30 //Print Optional(1) 31 //二維數(shù)組 32 arr2[1,2] = 22 33 print(arr2) 34 //Print Dim<Int>(dimension: [1, 2], array: [2, 22], product: 2, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2)") 35 let num2 = arr2[1,1] 36 print(num2) 37 //Print Optional(22) 38 //三維數(shù)組 39 arr3[1,1,1] = 33 40 print(arr3) 41 //Print Dim<Int>(dimension: [1, 2, 3], array: [33, 3, 3, 3, 3, 3], product: 6, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2,3Dimension: 3)") 42 let num3 = arr3[1,1,1] 43 print(num3) 44 //Print Optional(33) 45 //四維數(shù)組 46 arr4[1,1,1,1] = 44 47 print(arr4) 48 //Print Dim<Int>(dimension: [1, 2, 3, 4], array: [44, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], product: 24, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2,3Dimension: 3,4Dimension: 4)") 49 let num4 = arr4[1,1,1,1] 50 print(num4) 51 //Print Optional(44) 52 //五維數(shù)組 53 arr5[1,1,1,1,1] = 55 54 print(arr5) 55 //Print Dim<Int>(dimension: [1, 2, 3, 4, 5], array: [55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], product: 120, arrayInfo: " Array<T>(1Dimension: 1,2Dimension: 2,3Dimension: 3,4Dimension: 4,5Dimension: 5)") 56 let num5 = arr5[1,1,1,1,1] 57 print(num5) 58 //Print Optional(55) 59 //......?
轉(zhuǎn)載于:https://www.cnblogs.com/strengthen/p/9844577.html
總結(jié)
以上是生活随笔為你收集整理的[Swift]多维数组的表示和存储:N维数组映射到一维数组(一一对应)!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: v1.0.2-2017.04.26
- 下一篇: 小程序上拉加载,下拉刷新