我有这段代码生成所有长度为n的二进制序列。
所以:
allBitsSeqs(2) gives a 1-by-n int slice [[1 1][0 0] [1 0] [0 1]]
这是代码:
func allBitSeqs(n int) [][]int {
seq := [][]int{{1}, {0}}
for floor := 1; floor < n; floor++ {
remember := [][]int{}
for i := 0; i < len(seq); i++ {
one := append(seq[i], 1)
remember = append(remember, one)
zero := append(seq[i], 0)
remember = append(remember, zero)
}
seq = remember
}
return seq
}
游乐场链接:https://play.golang.org/p/s40RS7qEKfL
问题是,当n = 4或更大时,我得到:
[[1 1 1 0] [1 1 1 0] [1 1 0 0] [1 1 0 0] [1 0 1 0] [1 0 1 0] [1 0 0 0] [1 0 0 0] [0 1 1 0] [0 1 1 0] [0 1 0 0] [0 1 0 0] [0 0 1 0] [0 0 1 0] [0 0 0 0] [0 0 0 0]]
注意它们如何成对重复。
我尝试了一些调试,我认为它与Go需要分配更多空间时如何复制其片有关。
最佳答案
slice 是基础数组的 View 。如果您有多个使用同一基础数组的 slice ,那么如果您不知道 slice 的工作方式,则可能会得到意外的结果。
one := append(seq[i], 1)
说,
one
是指向一个数组的 slice ,该数组具有容纳添加的元素的能力。类似于以下内容:[ 1 1 . . . ]
阵列容量为5,前两个元素设置为1( slice len = 2)。当您添加另一个1时,它将变为:
[ 1 1 1 . .]
然后您执行以下操作:
remember = append(remember, one)
这样,您添加了一个指向上面的数组的 slice ,len = 3,capacity = 5。
然后:
zero := append(seq[i], 0)
请记住,seq [i]仍指向同一数组。另外,seq [i]具有len = 2。因此,数组变为:
[ 1 1 0 . . ]
那就是你的
zero
。但是,当您添加0时,您还更改了 slice one
。最后,您同时指向zero
的one
和[1 1 0 . .]
。长话短说:将 slice 分配给变量时,将 View 分配给数组。如果您修改基础数组的内容,则 View 的内容也会更改。
要修复:创建一个新的 slice ,复制数据,并存储该副本。
关于go - 生成二进制序列时, slice 追加无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59081379/