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回答
-
这个我们可以对照着那节slice的实现来看一下。slice的下面有一个真实存在的数组。如果slice只是指向其中的一段,那么append就会覆盖底层的数组中后面的元素。如果这样的话,很可能需要先copy出来
012018-11-24
相似问题