Heim >Backend-Entwicklung >Golang >Die Reihenfolge „sort.Slice' ist undefiniert
Der
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.
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] }
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) }
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"]
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]
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] })
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
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.
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 b
是 true
如果只有 a
或只有 b
是 true
。在 go 中,没有逻辑 xor
运算符,但 a xor b
相当于 a != b
:
true
(否则为 false
Wenn ein leerer String „erkannt“ wird, ist das Ergebnis
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] })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!