slice添加元素时,之前的元素会被修改

来源:3-3 切片的操作

tom睡着了

2018-11-22

老师您好,我在用append时发现会修改之前添加到slice数组中的内容。
下面的代码时leetcode的77号问题,题目是列出从[1…n]取k个数的所有组合,我使用递归来实现,generateCombine是我实现的递归函数。当程序首次执行到54行时,此时input=[4,5], aRes=[1,2,3],在经过53行的循环后,result应该是[[1,2,3,4],[1,2,3,5]],可是实际却是[[1,2,3,5],[1,2,3,5]]。调试过程中发现,在第二次运行到
54行的append(aRes, input[i])时,result中的[1,2,3,4]会变成[1,2,3,5],我不太能够理解为什么会发生这样的情况,我认为可能是引用的问题,所以做了56到59行的修改,能够得到正确的答案。但是我在main方法(23到29行)中又尝试模拟了下这种情况,得到的结果是正常的[[1,2,3,4],[1,2,3,5]],所以非常困惑到底是什么原因导致了[1,2,3,4]再经过append(aRes,input[i])后会变成[1,2,3,5]。希望老师能够点拨下。


 1. // 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
 2. 
 3. // 示例:
 4. 
 5. // 输入: n = 4, k = 2
 6. // 输出:
 7. // [
 8. //   [2,4],
 9. //   [3,4],
 10. //   [2,3],
 11. //   [1,2],
 12. //   [1,3],
 13. //   [1,4],
 14. // ]
 15. package main
 16. 
 17. import "fmt"
 18. 
 19. func main() {
 20. 	combine(5, 4)
 21. 	fmt.Println(result)
 22. 
 23. 	// arr := []int{1, 2, 3}
 24. 	// res := make([][]int, 0, 0)
 25. 	// input := []int{4, 5}
 26. 	// for i := 0; i < len(input); i++ {
 27. 	// 	res = append(res, append(arr, input[i]))
 28. 	// }
 29. 	// fmt.Println(res)
 30. }
 31. 
 32. var (
 33. 	count  int
 34. 	result [][]int
 35. )
 36. 
 37. func combine(n int, k int) [][]int {
 38. 	count = k
 39. 	result = make([][]int, 0, 0)
 40. 	var input = make([]int, 0, 0)
 41. 	if k > n || k == 0 {
 42. 		return result
 43. 	}
 44. 	for i := 1; i <= n; i++ {
 45. 		input = append(input, i)
 46. 	}
 47. 	generateCombine(make([]int, 0, 0), input)
 48. 	return result
 49. }
 50. 
 51. func generateCombine(aRes []int, input []int) {
 52. 	if len(aRes) == count-1 {
 53. 		for i := 0; i < len(input); i++ {
 54. 			result = append(result, append(aRes, input[i]))
 55. 
 56. 			// tmp := make([]int, 0, 0)
 57. 			// tmp = append(tmp, aRes...)
 58. 			// tmp = append(tmp, input[i])
 59. 			// result = append(result, tmp)
 60. 		}
 61. 		return
 62. 	}
 63. 
 64. 	for i := 0; i < len(input); i++ {
 65. 		generateCombine(append(aRes, input[i]), input[i+1:])
 66. 	}
 67. 
 68. }

写回答

1回答

ccmouse

2018-11-24

这个我们可以对照着那节slice的实现来看一下。slice的下面有一个真实存在的数组。如果slice只是指向其中的一段,那么append就会覆盖底层的数组中后面的元素。如果这样的话,很可能需要先copy出来

0
1
tom睡着了
感谢老师,我把那一节又看了一遍,理解了这个问题。
2018-11-24
共1条回复

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程