前言
在刷题的时候,有时候写dfs,我总喜欢拼凑切片,但是在debug的时候发现切片总是莫名结果会多出很多零,这就引起了我的好奇心,为什么我拼凑切片会出错,错在哪里?
错误示范
见下,我的目标是去除原切片下标i的元素,组成新的切片,进行下一次的递归
func main() { cnt := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} errDemoDfs(cnt) } func errDemoDfs(cnt []int) { for i := 0; i < len(cnt); i++ { nextCnt := make([]int, len(cnt)-1) copy(nextCnt, cnt[:i]) copy(nextCnt, cnt[i+1:]) fmt.Println(nextCnt) errDemoDfs(nextCnt) } }
... [2 3 4 5 6 7 8 9] [3 4 5 6 7 8 9 0] [4 5 6 7 8 9 0 0] [5 6 7 8 9 0 0 0] [0 0] [0] [] ....
错误原因
看输出发现,怎么新切片末尾是0,和我预取的结果不一致啊,why?随后debug
发现原切片,cnt[:i],cnt[i+1:],都是正常的。恍然大悟!原来是我copy用错了
copy的用法:
1. copy(dst,src)
2. 拷贝min(len(dst),len(src))个元素
3. 每次都从dst下标0开始赋值
看第三个步骤,每次都从下标0开始赋值,也就是说
copy(nextCnt, cnt[:i]) copy(nextCnt, cnt[i+1:])
cnt[i+1:]的元素覆盖了cnt[:i]
有时候深拷贝切片我会用copy,然后遇到想要去除一个元素的情况,我偷懒也用copy,这就导致bug出现了
正常用法
那么如果想要深拷贝,并且去除原数组的一个元素该如何写呢
func main() { cnt := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} acDemoDfs(cnt) } func acDemoDfs(cnt []int) { for i := 0; i < len(cnt); i++ { nextCnt := make([]int, 0, len(cnt)-1) nextCnt = append(nextCnt, cnt[:i]...) nextCnt = append(nextCnt, cnt[i+1:]...) fmt.Println(nextCnt) acDemoDfs(nextCnt) } }