golang组合生成出错
我正在处理一个编程问题 给定两个整数n和k,返回1中k个数的所有可能组合。。。n 当输入n=5,k=4时,输出应该是[[1,2,3,4],[1,2,3,5],[1,2,4,5],[1,3,4,5],[2,3,4,5],[2,3,4,5],下面是我的golang解golang组合生成出错,go,Go,我正在处理一个编程问题 给定两个整数n和k,返回1中k个数的所有可能组合。。。n 当输入n=5,k=4时,输出应该是[[1,2,3,4],[1,2,3,5],[1,2,4,5],[1,3,4,5],[2,3,4,5],[2,3,4,5],下面是我的golang解 func combine(n int, k int) [][]int { result := [][]int{} comb := []int{} subcom(0, k, n, &comb, &r
func combine(n int, k int) [][]int {
result := [][]int{}
comb := []int{}
subcom(0, k, n, &comb, &result)
return result
}
func subcom(s, k, n int, comb *[]int, result *[][]int) {
if k > 0 {
for i := s + 1; i <= n-k+1; i++ {
c := append(*comb, i)
subcom(i, k-1, n, &c, result)
}
} else {
*result = append(*result, *comb)
}
}
函数组合(n int,k int)[]int{
结果:=[]int{}
梳:=[]int{}
子COM(0、k、n、梳和结果)
返回结果
}
func subcom(s,k,n int,comb*[]int,result*[]int){
如果k>0{
对于i:=s+1;i这是使用
append
时的常见错误
当您的代码运行c:=append(*comb,i)
时,它尝试首先使用基础数组中分配的内存来添加新项,并且仅在失败时创建一个新片。这将[1 2 3 4]
更改为[1 2 3 5]
,因为它们共享相同的基础内存
若要解决此问题,请在要追加到结果中时复制:
now := make([]int,len(*comb))
copy(now,*comb)
*result = append(*result,now)
或者使用复制的快捷方式:
*result = append(*result, append([]int{},*comb...))
更新:
要理解我所说的底层内存,我们应该理解Go切片的内部模型
在Go中,切片有一个名为SliceHeader
的数据结构,可以通过reflect
包访问该数据结构,当您使用unsafe.Sizeof
和taking address时,会引用该数据结构
SliceHeader
负责三个元素:Len
、Cap
和一个Ptr
。前两个是trivail:它们是Len()
和Cap()
的对象。最后一个是一个uintptr
,指向该切片包含的数据的内存
当您浅层复制一个切片时,会创建一个新的
SliceHeader
,但内容相同,包括Ptr
。因此底层内存不会被复制,而是共享。您的意思是c:=append(*comb,i)
首先将i添加到comb,然后决定是否有必要为c创建一个新的切片?感谢分享博客,我已经读完了它,它帮助了很多。但是还有一件事,当我在结果中打印切片的地址时:0xc00018260ath,0xc00018260ath,0xc00018280ath,0xc000182a0ath,0xc000182c0ath,0xc000182c0ath
f第一个和第二个共用同一个地址,但其他人没有,我想不出是什么原因reason@kasheemlew我已经更新了我的答案来解决这个问题。