Go切片的append方法导致原切片数据错乱,如何解决?

题目:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)
思路:遍历元素的同时,增加进当前已存在的子集中

相关代码

func Subsets(nums []int) [][]int {
    size := len(nums)
    res := [][]int{nil}
    if size == 0 {
        return res
    }

    for i := 0; i < size; i++ {
        for _, tmp := range res {
            res = append(res, append(tmp, nums[i]))
        }
        fmt.Println(i, res)  // 由初始的nil,增加数组元素,形成新的子集集合
    }
    return res
}

问题描述

输入数组 = [9, 0, 3, 5, 7], 期待打印的得到的结果为:
0 [[] [9]]
1 [[] [9] [0] [9 0]]
2 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3]]
3 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5]]
4 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5] [7] [9 7] [0 7] [9 0 7] [3 7] [9 3 7] [0 3 7] [9 0 3 7] [5 7] [9 5 7] [0 5 7] [9 0 5 7] [3 5 7] [9 3 5 7] [0 3 5 7] [9 0 3 5 7]]

实际结果为:
0 [[] [9]]
1 [[] [9] [0] [9 0]]
2 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3]]
3 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5]]
4 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 7] [7] [9 7] [0 7] [9 0 7] [3 7] [9 3 7] [0 3 7] [9 0 3 7] [5 7] [9 5 7] [0 5 7] [9 0 5 7] [3 5 7] [9 3 5 7] [0 3 5 7] [9 0 3 7 7]]

请问,为什么实际结果中加粗的地方会数据错乱,得不到想要的[9, 0, 3, 5, 7]呢?

阅读 3.4k
1 个回答

slice 都是引用原数组的原地操作, 为避免引起的副作用, 需要拷贝数组

package main

import "fmt"

func combine(src[]int, num int)[]int{
    var dest = make([]int, len(src))
    copy(dest, src)
    return append(dest,num)
}

func Subsets(nums []int) [][]int {

    size := len(nums)

    res := [][]int{nil}
    if size == 0 {
        return res
    }

    for i := 0; i < size; i++ {
        for _, item := range res {
            res = append(res, combine(item, nums[i]))
        }
        fmt.Println(i, res)  // 由初始的nil,增加数组元素,形成新的子集集合
    }
    return res
}


func main(){

    nums :=[]int {9, 0, 3, 5, 7    }
    Subsets(nums)

}

将会输出

0 [[] [9]]
1 [[] [9] [0] [9 0]]
2 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3]]
3 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5]]
4 [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5] [7] [9 7] [0 7] [9 0 7] [3 7] [9 3 7] [0 3 7] [9 0 3 7] [5 7] [9 5 7] [0 5 7] [9 0 5 7] [3 5 7] [9 3 5 7] [0 3 5 7] [9 0 3 5 7]]

参考:
https://segmentfault.com/n/13...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题