Die Reihenfolge „sort.Slice' ist undefiniert

王林
Freigeben: 2024-02-10 12:12:10
nach vorne
1096 Leute haben es durchsucht

Der

`sort.Slice` 顺序是不确定的

php-Editor Strawberry stellt Ihnen einige wichtige Informationen zur Funktion „sort.Slice“ vor. In der Go-Sprache wird die Funktion „sort.Slice“ zum Sortieren von Slices verwendet, die Reihenfolge der sortierten Ergebnisse ist jedoch nicht definiert. Das heißt, für denselben Eingabeabschnitt können die Ergebnisse der Sortierung jedes Mal unterschiedlich sein. Dies liegt daran, dass die Funktion „sort.Slice“ einen schnellen und effizienten Sortieralgorithmus verwendet, die spezifische Sortierreihenfolge jedoch auf bestimmten Bedingungen der Eingabedaten basiert. Daher sollten wir uns bei der Verwendung der Funktion „sort.Slice“ des Nichtdeterminismus der Sortierergebnisse bewusst sein, um Probleme in Szenarien zu vermeiden, die auf einer bestimmten Sortierreihenfolge basieren.

Frageninhalt

Ich versuche sort.slice 对字符串切片进行排序。我希望它们按字母顺序排序,除了我希望空字符串出现在所有其他字符串之后(因此我不能只使用 sort.strings) aus der Go-Standardbibliothek zu verwenden.

Für die weniger Funktion würde das meiner Meinung nach funktionieren:

func(i, j int) bool {
    return s[j] == "" || s[i] < s[j]
}
Nach dem Login kopieren

Allerdings scheine ich zufällige Antworten basierend auf der Reihenfolge der Eingaben zu bekommen. Das ist mwe:

package main

import (
    "fmt"
    "math/rand"
    "sort"
    "time"
)

func main() {
    s := []string{"", "foo", "bar", "baz"}

    rand.seed(time.now().unix())
    rand.shuffle(len(s), func(i, j int) {
        s[i], s[j] = s[j], s[i]
    })
    fmt.printf("%q\n", s)

    sort.slice(s, func(i, j int) bool {
        return s[j] == "" || s[i] < s[j]
    })
    fmt.printf("%q\n", s)
}
Nach dem Login kopieren

Dies ist das Ergebnis einer mehrmaligen Ausführung:

$ go run ./z
["" "foo" "baz" "bar"]
["bar" "baz" "foo" ""]
$ go run ./z
["baz" "" "foo" "bar"]
["bar" "" "baz" "foo"]
$ go run ./z
["bar" "foo" "" "baz"]
["" "bar" "baz" "foo"]
$ go run ./z
["bar" "foo" "baz" ""]
["" "bar" "baz" "foo"]
Nach dem Login kopieren

Workaround

Das liegt daran, dass Ihre less()-Funktion nicht sagt, was Sie wollen.

Sie sagten, Sie möchten, dass die leere Zeichenfolge nach allen nicht leeren Zeichenfolgen sortiert wird. Deine Logik:

return s[j] == "" || s[i] < s[j]
Nach dem Login kopieren

Dadurch erfahren wir, ob das zweite "",那么第一个就更少。这或多或少是正确的(除非两者都是空的,“is-less”并不是真的:它们是相等的)。但是,如果第一个是 "" 而第二个不是怎么办?那么你的函数应该返回 false 但它返回 s[i] < s[j]。如果第二个不为空,则为 true,告诉 "" kleiner als das andere ist, was genau das Gegenteil von dem ist, was Sie wollen.

Die richtige „ist-weniger“-Beziehung sieht so aus:

sort.slice(s, func(i, j int) bool {
    if s[j] == "" && s[i] != "" {
        return true
    }
    if s[i] == "" && s[j] != "" {
        return false
    }
    return s[i] < s[j]
})
Nach dem Login kopieren

Wenn nur das zweite "" ist, möchten Sie, dass das erste weniger ist. Wenn nur das erste leer ist, soll es „nicht kleiner als“ sein. Ansonsten wird die normale Reihenfolge (byteweise) verwendet.

Probieren Sie es auf dem Go-Spielplatz aus.

Beachten Sie, dass diese Funktion false zurückgibt, wenn sowohl der erste als auch der zweite Wert leer sind, da false,因为 "" 不小于 "" (它们相等)。这是要返回的正确值,尽管在此处返回 true nicht kleiner als

ist (sie sind gleich). Dies ist der korrekte Wert, der zurückgegeben werden soll, obwohl die Rückgabe von true hier immer noch zur korrekten Reihenfolge führt (das Vertauschen leerer Elemente führt zum gleichen Ergebnis), aber dies kann zu weniger Vertauschungen führen.

Verwenden Sie die XOR-Transformationslogik

Bitte beachten Sie, dass in der benutzerdefinierten Logik, wenn nur eine Zeichenfolge leer ist, diese von der normalen Reihenfolge abweicht. Dies ist die logische XOR (XOR)-Beziehunga xor btrue 如果只有 a 或只有 btrue。在 go 中,没有逻辑 xor 运算符,但 a xor b 相当于 a != b:

.

true(否则为 falseWenn ein leerer String „erkannt“ wird, ist das Ergebnis

wenn der zweite leere String leer ist). So können wir diese Identitätstransformation auf unsere Logik anwenden:

sort.Slice(s, func(i, j int) bool {
    // Move empty elements to the end:
    if (s[i] == "") != (s[j] == "") { // If only one is empty
        return s[j] == ""
    }
    return s[i] < s[j]
})
Nach dem Login kopieren
Das ist kürzer und wahrscheinlich effizienter, aber wie Sie sehen, ist es schwieriger zu verstehen. Verwenden Sie diese Option nur, wenn die Leistung wichtig ist. Probieren Sie es auf dem Go-Spielplatz aus. 🎜

Das obige ist der detaillierte Inhalt vonDie Reihenfolge „sort.Slice' ist undefiniert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!