append() may modify the original slice (2d slice recursively)

WBOY
Release: 2024-02-06 08:27:04
forward
446 people have browsed it

append() 可能会修改原始切片(2d 切片递归)

Problem content

(The encoding problem is to generate solutions for all combinations whose sum reaches the target, the number of times each element in candidate arr is not Restricted.)

2D[][]int Slice theList Passed by reference in recursion appending []int (tmpCombo) , but after appending, one of the elements is modified, [3 3 3 3 3 3] is changed to [3 3 3 3 3 2]. So I have to copy tmpCombo before executing append(). append(arr, ele) Did the original arr slice change? If so, I should observe more of the original arr being modified, but this only happens once. So I'm actually confused about how this slice append() works.

https://go.dev/play/p/PH10SxiF7A5

<code>
...
theList: [.... [3 3 3 3 3 3]]
theList: [.... [3 3 3 3 3 2] [3 3 3 3 2 2 2]]
</code>
Copy after login

(I also tried doing a for loop and continuing to append to the slice, the original slice didn't change at all...)

package main

import (
    "fmt"
    "sort"
)

func combinationSum(candidates []int, target int) [][]int {
    sort.Sort(sort.Reverse(sort.IntSlice(candidates)))

    var theList [][]int
    var tmpCombo []int
    rCombo(candidates, target, 0, tmpCombo, &theList)

    return theList
}

func rCombo(candidates []int, target int, index int, tmpCombo []int, theList *[][]int) {
    if index >= len(candidates) {
        fmt.Println("index:", index)
        return
    }
    // fmt.Println(target)
    if candidates[index] > target {
        rCombo(candidates, target, index+1, tmpCombo, theList)
        return
    }

    for i:=index; i<len(candidates); i++ {
        if candidates[i] < target {
                rCombo(candidates, target-candidates[i], i, append(tmpCombo, candidates[i]), theList)
        } else if candidates[i] == target {

            // NOTE: simply append tmpCombo will give weird output [3 3 3 3 3 3] changed to [3 3 3 3 3 2].              
            *theList = append(*theList,  append(tmpCombo, target))

            // cpyCombo := make([]int, len(tmpCombo))
            // copy(cpyCombo, tmpCombo)
            // *theList = append(*theList,  append(cpyCombo, target))

            // appended slice didn't change address so tmpCombo was modified
            for i:=0; i<len(*theList); i++ {
                fmt.Printf("%d %p ", (*theList)[i], (*theList)[i])
            }
            fmt.Println()

            // fmt.Println("cc", tmpCombo, candidates[i], append(cpyCombo, candidates[i]), theList )
        }
    }
}

func main() {
    // 2,3,5
    candidates := []int{7,3,2}
    target := 18
    combinationSum(candidates, target)

 // test: this does not change the original s...
// var s []int = make([]int, 6)
// // var x []int

// for i:=0; i<200; i++ {
//  x := append(s, i)
//  fmt.Println(x, s)
// }
}
Copy after login

Correct answer


Since this answer illustrates the same problem, I understand nowhttps://www.php.cn/link/0d924f0e6b3fd0d91074c22727a53966一个>.

Basically, if a slice stores the data in one location with the specified capacity, but has the length as a separate property... in my case, doing multiple append(tmpCombo, target) The data in tmpCombo is actually modified because the variable isn't reallocated/updated with the new length, and the underlying data at the same location is modified (when not reallocated).

tldr. Make sure to pass a new copy of the same data using one of the following methods:

make()Create a new slice and copy()End (make()Allocate specific capacity)

or

append(nil []int, arr...]. (append() may allocate more memory, but is suitable for frequent modifications)

The above is the detailed content of append() may modify the original slice (2d slice recursively). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template