arn*_*nab 9 arrays go multidimensional-array dynamic-arrays
我想在Go中创建一个2d数组:
board := make([][]string, m)
for i := range board {
board[i] = make([]string, n)
}
Run Code Online (Sandbox Code Playgroud)
但是,鉴于其详细程度,我想知道是否有更好或更简洁的方法来处理这个问题(要么生成动态数组,要么使用不同/惯用的数据结构来处理这样的棋盘游戏数据)?
背景:
Jam*_*dge 13
您在示例代码中构建的内容不是2D数组,而是切片切片:每个子切片的长度可以与此类型不同,这就是为每个切片分别进行分配的原因.
如果你想用单个分配来表示电路板,一个选项是分配一个片,然后使用简单的算法来确定元素的位置.例如:
board := make([]string, m*n)
board[i*m + j] = "abc" // like board[i][j] = "abc"
Run Code Online (Sandbox Code Playgroud)
您描述的方式创建了一个切片切片,它看起来类似于您想要的二维数组。我建议你将类型更改为 uint8,因为你只关心 3 个状态nothing/ first/second玩家。
这会单独分配每一行(至少m + 1 allocs/op在基准测试中您会看到)。这并不是很好,因为不能保证单独的分配会彼此靠近。
为了保持局部性,你可以这样做:
M := make([][]uint8, row)
e := make([]uint8, row * col)
for i := range M {
a[i] = e[i * col:(i + 1) * col]
}
Run Code Online (Sandbox Code Playgroud)
这最终只会有 2 次分配,并且切片的切片将保持数据局部性。请注意,您仍然可以访问M2d 格式的M[2][6].
一个很好的视频,解释了如何更快地做到这一点。
小智 5
对于多维数组,我们可以有两种用例中的任何一种,
对于用例 1
matr := [5][5]int{}
Run Code Online (Sandbox Code Playgroud)
对于用例 2
var m, n int
fmt.Scan(&m, &n)
var mat = make([][]int, m)
for i := range mat {
mat[i] = make([]int, n)
fmt.Printf("Row %d: %v\n", i, mat[i])
}
Run Code Online (Sandbox Code Playgroud)
总之,我们要依赖make创建动态数组