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

我正在处理一个编程问题

给定两个整数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, &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我已经更新了我的答案来解决这个问题。