英文:
Why does slice value change?
问题
被附加到二维切片的切片的值稍后发生了变化。为什么会这样呢?
完整的代码如下:
import "sort"
import "fmt"
func combinationSum(candidates []int, target int) [][]int {
sort.Ints(candidates)
var ret [][]int
var curlist []int
combinationSumRecursive(candidates, target, 0, curlist, &ret)
fmt.Println("ret", ret)
return ret
}
func combinationSumRecursive(candidates []int, target int, curCandidateIdx int, curlist []int, ret *[][]int) {
if target == 0 {
fmt.Println("put", curlist)
*ret = append(*ret, curlist)
return
}
for i := curCandidateIdx; i < len(candidates); i++ {
if candidates[i] > target {
break
}
combinationSumRecursive(candidates, target-candidates[i], i, append(curlist, candidates[i]), ret)
}
}
输入为:
[7,3,2]
18
输出如下:
put [2 2 2 2 2 2 2 2 2]
put [2 2 2 2 2 2 3 3]
put [2 2 2 2 3 7]
put [2 2 2 3 3 3 3]
put [2 2 7 7]
put [2 3 3 3 7]
put [3 3 3 3 3 3]
ret [[2 2 2 2 2 2 2 2 2] [2 2 2 2 2 7 3 3] [2 2 2 2 3 7] [2 2 2 3 3 3 3] [2 2 7 7] [2 3 3 3 7] [3 3 3 3 3 3]]
ret
中的第二个切片发生了变化。预期是 [2 2 2 2 2 2 3 3]
。
谢谢任何帮助。
英文:
The value of a slice that be appended to a two-dimension slice, is changed later。 Why does it happen?
The full code is below:
import "sort"
import "fmt"
func combinationSum(candidates []int, target int) [][]int {
sort.Ints(candidates)
var ret [][]int
var curlist []int
combinationSumRecursive(candidates, target, 0, curlist, &ret)
fmt.Println("ret", ret)
return ret
}
func combinationSumRecursive(candidates []int, target int, curCandidateIdx int, curlist []int, ret *[][]int) {
if target == 0 {
fmt.Println("put", curlist)
*ret = append(*ret, curlist)
return
}
for i:=curCandidateIdx;i<len(candidates);i++{
if candidates[i] > target {
break
}
combinationSumRecursive(candidates, target - candidates[i], i, append(curlist, candidates[i]), ret)
}
}
INPUT is :
[7,3,2]
18
OUTPUT is below:
put [2 2 2 2 2 2 2 2 2]
put [2 2 2 2 2 2 3 3]
put [2 2 2 2 3 7]
put [2 2 2 3 3 3 3]
put [2 2 7 7]
put [2 3 3 3 7]
put [3 3 3 3 3 3]
ret [[2 2 2 2 2 2 2 2 2] [2 2 2 2 2 7 3 3] [2 2 2 2 3 7] [2 2 2 3 3 3 3] [2 2 7 7] [2 3 3 3 7] [3 3 3 3 3 3]]
The second slice in ret
is changed. [2 2 2 2 2 2 3 3]
was expected.
Thanks to any help.
答案1
得分: 1
这是由于在第combinationSumRecursive(candidates, target - candidates[i], i, append(curlist, candidates[i]), ret)
行的追加操作中,切片curlist
的改变导致的。
解决方法是在将其传递给下一个递归级别之前,将curlist
重新分配为追加的结果。
package main
import "sort"
import "fmt"
func combinationSum(candidates []int, target int) [][]int {
sort.Ints(candidates)
var ret [][]int
var curlist []int
combinationSumRecursive(candidates, target, 0, curlist, &ret)
fmt.Println("ret", ret)
return ret
}
func combinationSumRecursive(candidates []int, target int, curCandidateIdx int, curlist []int, ret *[][]int) {
if target == 0 {
fmt.Println("put", curlist)
*ret = append(*ret, append([]int(nil), curlist...))
return
}
for i := curCandidateIdx; i < len(candidates); i++ {
if candidates[i] > target {
break
}
curlist = append(curlist, candidates[i])
combinationSumRecursive(candidates, target-candidates[i], i, curlist, ret)
curlist = curlist[:len(curlist)-1]
}
}
func main() {
combinationSum([]int{7, 3, 2}, 18)
}
这将产生以下结果:
put [2 2 2 2 2 2 2 2 2]
put [2 2 2 2 2 2 3 3]
put [2 2 2 2 3 7]
put [2 2 2 3 3 3 3]
put [2 2 7 7]
put [2 3 3 3 7]
put [3 3 3 3 3 3]
ret [[2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 3 3] [2 2 2 2 3 7] [2 2 2 3 3 3 3] [2 2 7 7] [2 3 3 3 7] [3 3 3 3 3 3]]
[编辑] 首先阅读这篇文章。它解释了尽管您看到切片头的地址发生了变化,但追加后的支持数组仍然可能是相同的。
然后,这篇文章是您的情况下发生的示例。
问题在于在您的情况下,由于递归调用和将当前索引重新定位到curlist
中,很难看到这一点。
英文:
This is caused by the change of the slice curlist
in the append on line combinationSumRecursive(candidates, target - candidates[i], i, append(curlist, candidates[i]), ret)
.
A solution is to reassign curlist
to the appended result before passing it to the next recursive level.
package main
import "sort"
import "fmt"
func combinationSum(candidates []int, target int) [][]int {
sort.Ints(candidates)
var ret [][]int
var curlist []int
combinationSumRecursive(candidates, target, 0, curlist, &ret)
fmt.Println("ret", ret)
return ret
}
func combinationSumRecursive(candidates []int, target int, curCandidateIdx int, curlist []int, ret *[][]int) {
if target == 0 {
fmt.Println("put", curlist)
*ret = append(*ret, curlist)
return
}
for i := curCandidateIdx; i < len(candidates); i++ {
if candidates[i] > target {
break
}
curlist = append(curlist, candidates[i])
combinationSumRecursive(candidates, target-candidates[i], i, curlist, ret)
}
}
func main() {
combinationSum([]int{7, 3, 2}, 18)
}
This yields:
put [2 2 2 2 2 2 2 2 2]
put [2 2 2 2 2 2 3 3]
put [2 2 2 2 3 7]
put [2 2 2 3 3 3 3]
put [2 2 7 7]
put [2 3 3 3 7]
put [3 3 3 3 3 3]
ret [[2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 3 3] [2 2 2 2 3 7] [2 2 2 3 3 3 3] [2 2 7 7] [2 3 3 3 7] [3 3 3 3 3 3]]
[EDIT] First read this. That explains that although you see the addresses of the slice headers change the backing array can still be the same after an append.
Then this is an example of what happens in your case.
The problem is in your case is it hard to see because of the recursive calls and the re positioning of the current index into curlist
.
答案2
得分: 1
你只在target==0
时打印curlist
,但由于递归函数中的append(curlist, candidates[i])
,curlist
会不断变化。
如果你尝试使用其他候选项,例如:[5,3,2]
,你会注意到其他切片不仅仅是第二个切片会改变。
当target=0
时,尝试复制curlist
:
if target == 0 {
fmt.Println("put", curlist)
newCurlist := make([]int, len(curlist))
copy(newCurlist, curlist)
*ret = append(*ret, newCurlist)
return
}
这样应该可以解决问题!
英文:
You're printing the curlist
only when target==0
but it keeps changing due to the append(curlist, candidates[i])
in your recursive function.
If you try with other candidates, for example : [5,3,2]
you will notice that other slices change not only the second.
try making a copy of curlist
when the target=0
:
if target == 0 {
fmt.Println("put", curlist)
newCurlist := make([]int, len(curlist))
copy(newCurlist, curlist)
*ret = append(*ret, newCurlist)
return
}
this should work!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论