append函数修改底层数组:为什么递归算法中元素会意外被修改?
避免 append 函数修改底层数组
问题描述:
在利用 append 函数生成数组组合的算法中,发现当输入数组长度大于 5 时,某些元素会受到修改。尽管 append 应为指针传递,并且新声明了 next 数组,但较小的元素会被修改。
问题分析:
问题在于 append 函数的长度追加特性。虽然每次添加元素都会增加容量,但并不是逐个增加,而是以一定的倍数递增。因此,当底层数组被用满时,追加元素会直接申请一个更大的新数组。
示例说明:
以下示例演示了 append 长度追加的过程:
a := []int{} for i := 0; i < 10; i++ { a = append(a, i) fmt.println(cap(a)) }
输出:
1 2 4 4 8 8 8 8 16 16
可以看到,三次 append 增加了 2 个容量,随后直接申请了一个长度为 8 的数组,再往后又申请了一个长度为 16 的数组。
问题算法中的影响:
在问题算法中,插入 [1,2,3] 时生成的底层数组长度为 4。当递归回溯到 [1,2,3] 后面要追加元素 5 时,由于底层数组长度为 4,不必申请新的空间,直接在元数组上修改,导致 [1,2,3,4] 也修改为 [1,2,3,5]。
解决方案:
为新切片强制分配一个新的底层数组即可解决问题:
next := make([]int, len(pre)) copy(next, pre) next = append(next, (*nums)[i])
以上就是append函数修改底层数组:为什么递归算法中元素会意外被修改?的详细内容,更多请关注硕下网其它相关文章!