Golang:多维数组使用片对片策略,导致奇怪的输出



我在golang中为2d数组使用以下简单代码,其中APPEND函数会产生重复值,而不是追加。

package main
import "fmt"
func main() {
    var n int
    fmt.Scanf("%d", &n)
    array := [][]int{}
    row := make([]int, n)
    for _, _ = range row {
        for j, _ := range row {
            fmt.Scanf("%d", &row[j])
        }
        fmt.Println("Printing current Row", row)
        array = append(array, row)
        fmt.Println("Printing curent Array", array)
    }
    fmt.Println("Final Array", array)
}

但奇怪的是,这并没有出乎意料。如果假设我希望这件事发生(输入)

2
1 2
3 4

我运行这个程序,得到这个作为回报

2     //Dimension for matrix
1     //Iteration one begins
2
Printing current Row [1 2]
Printing curent Array [[1 2]]
3     //Iteration two begins
4
Printing current Row [3 4]
Printing curent Array [[3 4] [3 4]]
Final Array [[3 4] [3 4]]

我不明白为什么APPEND函数会导致重复条目。想知道如何纠正这一点也是CONCEPT

的基础

发生这种行为是因为您没有向array添加新的row切片。每次迭代只需读入覆盖先前值的相同row切片。试试下面的:

func main() {
    var n int
    fmt.Scanf("%d", &n)
    array := [][]int{}
    for i := 0; i < n; i++ {
        row := make([]int, n) // create a new slice to add next row values
        for j, _ := range row {
            fmt.Scanf("%d", &row[j])
        }
        fmt.Println("Printing current Row", row)
        array = append(array, row)
        fmt.Println("Printing curent Array", array)
    }
    fmt.Println("Final Array", array)
}

在第一个循环的每次迭代中使用新的切片,并检查错误

您将新数据读取到旧的同一切片,这就是您有重复数据的原因。

如果要使用append,请首先创建零长度的数组,并将n:
封顶array := make([][]int, 0, n)
然后将第一个循环更改为:for i := 0; i < n; i++ {
在这个循环中生成新的切片:row := make([]int, n)

双向:
使用附加(无fmt.Scan错误检查):

package main
import "fmt"
func main() {
    n := 0
    fmt.Scan(&n)
    slice := make([][]int, 0, n)
    for i := 0; i < n; i++ {
        row := make([]int, n)
        for j, _ := range row {
            fmt.Scan(&row[j])
        }
        slice = append(slice, row)
    }
    fmt.Println(slice)
}

不使用追加读取s[i][j](带错误检查):

package main
import "fmt"
func main() {
    var n int
    if m, err := fmt.Scan(&n); m != 1 {
        panic(err)
    }
    s := make([][]int, n)
    for i := 0; i < n; i++ {
        s[i] = make([]int, n)
        for j := 0; j < n; j++ {
            if m, err := fmt.Scan(&s[i][j]); m != 1 {
                panic(err)
            }
        }
    }
    fmt.Println(s)
}

输入:

2
1 2
3 4

输出:

[[1 2] [3 4]]

我认为这个测试示例代码足够清晰,可以
显示切片的工作方式(带注释输出):

package main
import "fmt"
func main() {
    s1 := [][]int{}
    s2 := []int{1, 2}
    s1 = append(s1, s2)
    fmt.Println(s1) // [[1 2]]
    s2[0], s2[1] = 3, 4
    fmt.Println(s1) // [[3 4]]
    s1 = append(s1, s2)
    fmt.Println(s1) // [[3 4] [3 4]]
    s2[0], s2[1] = 30, 40
    fmt.Println(s1) // [[30 40] [30 40]]
    fmt.Println(len(s2), cap(s2)) // 2 2
    s3 := [][]int{
        []int{1, 2},
        []int{3, 4},
        s2,
        s2,
    }
    fmt.Println(s3) // [[1 2] [3 4] [30 40] [30 40]]
    s2[0] = 100
    fmt.Println(s3) // [[1 2] [3 4] [100 40] [100 40]]
}

您创建了切片s1的切片,如下所示:
array[0]=行[0],行[1]
array[1]=行[0],行[1]

所以当你改变行时,它会看到两次。

相关内容

  • 没有找到相关文章

最新更新