Maison > développement back-end > Golang > le corps du texte

L'ordre `sort.Slice` n'est pas défini

王林
Libérer: 2024-02-10 12:12:10
avant
1097 Les gens l'ont consulté

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

l'éditeur php Strawberry vous présentera quelques informations importantes sur la fonction `sort.Slice`. En langage Go, la fonction `sort.Slice` est utilisée pour trier les tranches, mais l'ordre de ses résultats triés n'est pas défini. Autrement dit, pour une même tranche d’entrée, les résultats du tri peuvent être différents à chaque fois. En effet, la fonction « sort.Slice » utilise un algorithme de tri rapide et efficace, mais l'ordre spécifique de tri est basé sur des conditions spécifiques des données d'entrée. Par conséquent, lors de l'utilisation de la fonction « sort.Slice », nous devons être conscients du non-déterminisme des résultats du tri pour éviter les problèmes dans les scénarios qui reposent sur un ordre de tri spécifique.

Contenu de la question

J'essaie d'utiliser sort.slice 对字符串切片进行排序。我希望它们按字母顺序排序,除了我希望空字符串出现在所有其他字符串之后(因此我不能只使用 sort.strings) de la bibliothèque standard Go.

Pour le moins de fonctions, je pense que cela fonctionnerait :

func(i, j int) bool {
    return s[j] == "" || s[i] < s[j]
}
Copier après la connexion

Cependant, il semble que j'obtienne des réponses aléatoires en fonction de l'ordre d'entrée. C'est 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)
}
Copier après la connexion

Voici le résultat de l'exécution plusieurs fois :

$ 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"]
Copier après la connexion

Solution de contournement

C'est parce que votre fonction less() ne dit pas ce que vous voulez.

Vous avez dit que vous souhaitiez que la chaîne vide soit triée après toutes les chaînes non vides. Votre logique :

return s[j] == "" || s[i] < s[j]
Copier après la connexion

Cela nous indique si le second est "",那么第一个就更少。这或多或少是正确的(除非两者都是空的,“is-less”并不是真的:它们是相等的)。但是,如果第一个是 "" 而第二个不是怎么办?那么你的函数应该返回 false 但它返回 s[i] < s[j]。如果第二个不为空,则为 true,告诉 "" plus petit que l'autre, ce qui est exactement le contraire de ce que vous souhaitez.

La relation correcte "est-moins" est la suivante :

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]
})
Copier après la connexion

Si seulement le second est "", vous voulez que le premier soit inférieur. Si seul le premier est vide, vous voulez qu'il soit "pas moins que". Sinon, l'ordre normal (par octet) est utilisé.

Essayez-le sur le go terrain de jeu.

Notez que si les première et deuxième valeurs sont vides, cette fonction renverra false car false,因为 "" 不小于 "" (它们相等)。这是要返回的正确值,尽管在此处返回 true n'est pas inférieur à

(elles sont égales). C'est la valeur correcte à renvoyer, bien que renvoyer true ici entraînera toujours l'ordre correct (l'échange d'éléments vides entraînera le même résultat), mais cela peut entraîner moins d'échanges.

Utilisez la logique de transformation xor

Veuillez noter que dans la logique personnalisée, si une seule chaîne est vide, elle s'écartera de l'ordre normal. C'est la relation logique XOR (XOR)a xor btrue 如果只有 a 或只有 btrue。在 go 中,没有逻辑 xor 运算符,但 a xor b 相当于 a != b :

.

true(否则为 falseSi une chaîne vide est "détectée", le résultat est

si la deuxième chaîne vide est vide). Nous pouvons donc appliquer cette transformation identitaire à notre logique :

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]
})
Copier après la connexion
C'est plus court et probablement plus efficace, mais comme vous pouvez le voir, c'est plus difficile à comprendre. Utilisez cette option uniquement si les performances sont importantes. Essayez ceci sur le go terrain de jeu. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!