Heim >Backend-Entwicklung >Golang >Warum werden diese Tupel nicht korrekt generiert?

Warum werden diese Tupel nicht korrekt generiert?

WBOY
WBOYnach vorne
2024-02-09 10:00:111001Durchsuche

Warum werden diese Tupel nicht korrekt generiert?

Der PHP-Editor Apple stößt beim Schreiben von Code häufig auf Probleme. Eines der häufigsten Probleme ist die falsche Tupelgenerierung. Dies kann auf Codelogikfehler, Datentypkonflikte oder andere Fehler zurückzuführen sein. Bevor wir dieses Problem lösen, müssen wir den Code sorgfältig analysieren, mögliche Fehlerpunkte finden und sie einzeln beheben. Erst wenn das Problem gefunden wird, können entsprechende Reparaturen durchgeführt werden, um sicherzustellen, dass die Tupel korrekt generiert werden, um den normalen Betrieb des Codes sicherzustellen.

Frageninhalt

Ich habe an einem Projekt gearbeitet, bei dem ich alle möglichen Tupel einer bestimmten Länge aus einer Menge von (Plural-)Zahlen generieren muss. Zu diesem Zweck habe ich versucht, eine Version des Tuples[]-Befehls von Mathematica zu implementieren, habe jedoch festgestellt, dass nicht alle Tupel korrekt generiert wurden.

Nach langem Frust habe ich herausgefunden, dass mein Programm beim Generieren von Tupeln der Länge 4 Duplikate anstelle neuer Elemente hinzufügt, was bei Tupeln mit längerer Länge zu Problemen führt. Ich habe im Internet nach anderen ähnlichen Problemen gesucht und einen anderen Code für die gleiche Aufgabe gefunden. Dabei ist mir aufgefallen, dass meine Lösung ihrer ähnlich war. Ich weiß nicht, was mit mir los ist.

Nach weiterer Frustration stellte ich fest, dass alles gut funktioniert, wenn ich Elemente zur Liste hinzufüge, nur das Anhängen ist das Problem. Ich habe versucht herauszufinden, was mit meinem ursprünglichen Code nicht stimmte, habe aber nichts gefunden.

Unten ist der Code, den ich geschrieben habe, um das Problem zu veranschaulichen. Ich bin keineswegs ein professioneller Programmierer, daher müssen Sie mir verzeihen, wenn dies nicht die idiomatischste Art ist, diese Aufgabe zu lösen. Derzeit verwende ich die Funktion „tuplesByPrepend“ in meinem eigentlichen Code und sie funktioniert einwandfrei. Ich hoffe wirklich nur zu verstehen, was mit der Funktion „tuplesByAppend“ falsch läuft. Ebenso schien es auf der dritten, fünften, achten und jeder anderen Ebene, auf der ich es getestet habe, eine gute Leistung zu erbringen. Bei Bedarf kann ich weitere Informationen zu meinem Betriebssystem und Build usw. bereitstellen.

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

Workaround

In manchen Fällen funktioniert die folgende Zeile nicht wie erwartet:

next := append(u, v)

Dieses Beispiel zeigt, was passiert:

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

Um zu verhindern, dass das zugrunde liegende Array gemeinsam genutzt wird, ersetzen Sie next :=append(u, v) durch den folgenden Code:

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

Weitere Informationen finden Sie unter Go Slices: Verwendung und Interna.

Das obige ist der detaillierte Inhalt vonWarum werden diese Tupel nicht korrekt generiert?. 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