Rumah >pembangunan bahagian belakang >Golang >append() boleh mengubah suai kepingan asal (hirisan 2d secara rekursif)

append() boleh mengubah suai kepingan asal (hirisan 2d secara rekursif)

WBOY
WBOYke hadapan
2024-02-06 08:27:04473semak imbas

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

Kandungan masalah

(Masalah pengekodan adalah untuk menjana penyelesaian untuk semua kombinasi yang jumlahnya mencapai sasaran, dengan bilangan kali yang tidak terhad untuk setiap elemen dalam arr. calon)

Bagaimana

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

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>

(Saya pun cuba buat for loop dan terus melekat pada slice, slice asal tak berubah langsung...)

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

Jawapan betul


Memandangkan jawapan ini menggambarkan masalah yang sama, saya faham sekaranghttps://www.php.cn/link/0d924f0e6b3fd0d91074c22727a53966一个>.

Pada asasnya, jika kepingan menyimpan data dalam satu lokasi dengan kapasiti yang ditentukan, tetapi mempunyai panjang sebagai sifat berasingan... dalam kes saya, melakukan berbilang

data di dalamnya, kerana pembolehubah tidak diperuntukkan semula/ The panjang baharu dikemas kini dan data asas di lokasi yang sama diubah suai (apabila tidak diperuntukkan semula). append(tmpCombo, target) 实际上会修改 tmpCombo tldr. Pastikan anda menghantar salinan baharu data yang sama menggunakan salah satu kaedah berikut:

Peruntukkan kapasiti tertentu)make()新建切片并copy()结束(make()

atau

Boleh memperuntukkan lebih banyak ingatan, tetapi sesuai untuk pengubahsuaian yang kerap)append(nil []int, arr...]. (append()

Atas ialah kandungan terperinci append() boleh mengubah suai kepingan asal (hirisan 2d secara rekursif). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam