Heim  >  Artikel  >  Backend-Entwicklung  >  append() kann das Original-Slice modifizieren (2D-Slice rekursiv)

append() kann das Original-Slice modifizieren (2D-Slice rekursiv)

WBOY
WBOYnach vorne
2024-02-06 08:27:04442Durchsuche

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

Probleminhalt

(Das Codierungsproblem besteht darin, Lösungen für alle Kombinationen zu generieren, deren Summe das Ziel erreicht, und zwar mit unbegrenzter Häufigkeit für jedes Element in der Kandidatenanordnung.)

Wie

2D [][]int 切片 theList 在附加 []int (tmpCombo) 的递归中通过引用传递,但附加后,其中一个元素被修改,[3 3 3 3 3 3] 更改为 [3 3 3 3 3 2]。所以我必须在执行 append() 之前复制 tmpComboappend(arr, ele) 是否更改了原始 arr 切片?如果是这样,我应该观察到更多原始的 arr 被修改,但这种情况只发生一次。所以我实际上很困惑这个切片 append() funktioniert.

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>

(Ich habe auch versucht, eine for-Schleife zu erstellen und weiterhin an das Slice anzuhängen, das ursprüngliche Slice hat sich überhaupt nicht geändert ...)

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)
// }
}

Richtige Antwort


Da diese Antwort das gleiche Problem veranschaulicht, verstehe ich es jetzthttps://www.php.cn/link/0d924f0e6b3fd0d91074c22727a53966一个>.

Grundsätzlich gilt: Wenn ein Slice die Daten an einem Ort mit der angegebenen Kapazität speichert, aber die Länge als separate Eigenschaft hat, werden in meinem Fall mehrere append(tmpCombo, target) 实际上会修改 tmpCombo der darin enthaltenen Daten ausgeführt, da die Variable nicht neu zugewiesen wird Die neue Länge wird aktualisiert und die zugrunde liegenden Daten am selben Ort werden geändert (sofern sie nicht neu zugewiesen werden).

tldr. Stellen Sie sicher, dass Sie eine neue Kopie derselben Daten mit einer der folgenden Methoden übergeben:

make()新建切片并copy()结束(make()Spezifische Kapazität zuweisen)

oder

append(nil []int, arr...]. (append() Kann mehr Speicher zuweisen, ist aber für häufige Änderungen geeignet)

Das obige ist der detaillierte Inhalt vonappend() kann das Original-Slice modifizieren (2D-Slice rekursiv). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen