Rumah >pembangunan bahagian belakang >Golang >Mengapa tupel ini tidak dijana dengan betul?

Mengapa tupel ini tidak dijana dengan betul?

WBOY
WBOYke hadapan
2024-02-09 10:00:111004semak imbas

Mengapa tupel ini tidak dijana dengan betul?

Editor PHP Apple sering menghadapi beberapa masalah semasa menulis kod Salah satu masalah biasa ialah penjanaan tuple yang tidak betul. Ini mungkin disebabkan oleh ralat logik kod, ketidakpadanan jenis data atau ralat lain. Sebelum menyelesaikan masalah ini, kita perlu menganalisis kod dengan teliti, mencari titik ralat yang mungkin dan menyelesaikannya satu demi satu. Hanya apabila masalah ditemui boleh pembaikan yang sepadan dibuat untuk memastikan tupel dijana dengan betul untuk memastikan operasi normal kod.

Kandungan soalan

Saya telah mengusahakan projek yang memerlukan saya menjana semua tuple yang mungkin dengan panjang tertentu daripada set nombor (majmuk). Untuk melakukan ini, saya cuba melaksanakan versi perintah Tuples[] Mathematica, tetapi mendapati ia tidak menjana semua tupel dengan betul.

Selepas banyak kekecewaan, saya mendapati bahawa apabila program saya menghasilkan tupel panjang 4, ia menambah pendua dan bukannya elemen baharu, menyebabkan masalah dengan mana-mana tupel yang lebih panjang. Saya melihat dalam talian untuk melihat sama ada sesiapa mempunyai masalah lain yang serupa dan menemui beberapa kod lain untuk menyelesaikan tugas yang sama dan mendapati bahawa penyelesaian saya serupa dengan mereka. Saya tidak tahu apa yang salah dengan saya.

Selepas lebih banyak kekecewaan, saya mendapati bahawa jika saya menambah elemen pada senarai, semuanya berfungsi dengan baik, hanya menambah sahaja masalahnya. Saya cuba mencari apa yang salah dengan kod asal saya tetapi tidak menemui apa-apa.

Di bawah ialah kod yang saya tulis untuk menunjukkan masalah itu. Saya sama sekali bukan seorang pengekod profesional, jadi anda perlu memaafkan saya jika ini bukan cara yang paling idiomatik untuk menyelesaikan tugas ini. Pada masa ini, saya menggunakan fungsi tuplesByPrepend dalam kod sebenar saya dan ia berfungsi dengan baik, saya benar-benar berharap untuk memahami apa yang berlaku dengan fungsi tuplesByAppend. Begitu juga, ia kelihatan berprestasi baik pada tahap ketiga, kelima, kelapan, dan mana-mana tahap lain yang saya uji. Saya boleh memberikan lebih banyak maklumat tentang OS dan binaan saya dan semua itu jika perlu.

package main

import "fmt"

func tuplesByAppend[T any](list []T, depth int) [][]T {
    var l1 [][]T
    var l2 [][]T

    for _, v := range list {
        l1 = append(l1, []T{v})
    }

    for i := 1; i < depth; i++ {
        for _, u := range l1 {
            for _, v := range list {
                // Differs here
                next := append(u, v)
                // next is calculated properly, but added to l2 incorrectly at the fourth level only
                // at the fifth level it functions properly
                // fmt.Println(next)
                l2 = append(l2, next)
                // fmt.Println(l2)

                // it appears that at the fourth level it is writing over the previous entries
                // Printing here yields
                // [[1 1 1 1]]
                // [[1 1 1 2] [1 1 1 2]]
                // [[1 1 1 3] [1 1 1 3] [1 1 1 3]]
                // [[1 1 1 3] [1 1 1 3] [1 1 1 3] [1 1 2 1]]
                // [[1 1 1 3] [1 1 1 3] [1 1 1 3] [1 1 2 2] [1 1 2 2]]
                // and so on.
            }
        }
        l1 = l2
        l2 = [][]T{}
    }

    return l1
}

func tuplesByPrepend[T any](list []T, depth int) [][]T {
    var l1 [][]T
    var l2 [][]T

    for _, v := range list {
        l1 = append(l1, []T{v})
    }

    for i := 1; i < depth; i++ {
        for _, u := range l1 {
            for _, v := range list {
                // Differs here
                next := append([]T{v}, u...)
                l2 = append(l2, next)
            }
        }
        l1 = l2
        l2 = [][]T{}
    }

    return l1
}

func main() {
    ourlist := []int{1, 2, 3}
    ourdepth := 4
    appended := tuplesByAppend(ourlist, ourdepth)
    prepended := tuplesByPrepend(ourlist, ourdepth)

    // We should expect this slice to start [1 1 1 1] [1 1 1 2] [1 1 1 3] [1 1 2 1] ...
    // In fact, it starts                   [1 1 1 3] [1 1 1 3] [1 1 1 3] [1 1 2 3]
    fmt.Println(appended)
    // This slice is as expected
    fmt.Println(prepended)
}

Penyelesaian

Dalam sesetengah kes, baris berikut tidak berfungsi seperti yang anda jangkakan:

next := append(u, v)

Contoh ini menunjukkan perkara yang berlaku:

package main

import "fmt"

func main() {
    u := append([]int{1, 2}, 3)
    // The length is 3 but the capacity is 4.
    fmt.Printf("u %v\n  len: %d\n  cap: %d\n", u, len(u), cap(u))

    // Since u has enough capacity for the new element "4",
    // v1 will share the same underlying array.
    v1 := append(u, 4)
    fmt.Println("v1:", v1)

    // As what happened to v1, v2 will share the same underlying array too.
    // But the last element "4" in the underlying array is changed to "5".
    v2 := append(u, 5)
    fmt.Println("v2:", v2)

    // Since v1 uses the same underlying array, it sees the change in the last step.
    fmt.Println("v1:", v1)
}

Untuk menghalangnya daripada berkongsi tatasusunan asas, gantikan next :=append(u, v) dengan kod berikut:

next := make([]T, len(u)+1)
copy(next, u)
next[len(u)] = v

Lihat Go Slices: Penggunaan dan Dalaman untuk maklumat lanjut.

Atas ialah kandungan terperinci Mengapa tupel ini tidak dijana dengan betul?. 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