web-dev-qa-db-fra.com

Vérifiez si une tranche de chaîne contient une certaine valeur dans Go

Quelle est la meilleure façon de vérifier si une certaine valeur se trouve dans une tranche de chaîne? J'utiliserais un ensemble dans d'autres langues, mais Go n'en a pas.

Mon meilleur essai est jusqu'à présent:

package main

import "fmt"

func main() {
    list := []string{"a", "b", "x"}
    fmt.Println(isValueInList("b", list))
    fmt.Println(isValueInList("z", list))
}

func isValueInList(value string, list []string) bool {
    for _, v := range list {
        if v == value {
            return true
        }
    }
    return false
}

http://play.golang.org/p/gkwMz5j09n

Cette solution devrait être correcte pour les petites tranches, mais que faire pour les tranches contenant de nombreux éléments?

24
deamon

Si vous avez une tranche de chaînes dans un ordre arbitraire, la recherche d'une valeur dans la tranche nécessite O(n) heure. Cela s'applique à toutes les langues.

Si vous avez l'intention de faire une recherche encore et encore, vous pouvez utiliser d'autres structures de données pour accélérer les recherches. Cependant, la construction de ces structures nécessite au moins O(n) temps. Ainsi, vous n'obtiendrez d'avantages que si vous effectuez des recherches en utilisant la structure de données plus d'une fois.

Par exemple, vous pouvez charger vos chaînes dans une carte. Les recherches prendraient alors O(1) temps. Les insertions prennent également O(1) temps pour que la construction initiale prenne O(n) fois:

set := make(map[string]bool)
for _, v := range list {
    set[v] = true
}

fmt.Println(set["b"])

Vous pouvez également trier votre tranche de chaîne, puis effectuer une recherche binaire. Les recherches binaires se produisent dans O(log(n)) time. La construction peut prendre O (n * log (n)) time.

sort.Strings(list)
i := sort.SearchStrings(list, "b")
fmt.Println(i < len(list) && list[i] == "b")

Bien qu'en théorie étant donné un nombre infini de valeurs, une carte est plus rapide, en pratique, il est très probable que la recherche dans une liste triée soit plus rapide. Vous devez le comparer vous-même.

51
Stephen Weinberg

Pour remplacer des ensembles, vous devez utiliser un map[string]struct{}. C'est efficace et considéré comme idiomatique, les "valeurs" ne prennent absolument pas de place.

Initialisez l'ensemble:

set := make(map[string]struct{})

Mettez un article:

set["item"]=struct{}{}

Vérifiez si un élément est présent:

_, isPresent := set["item"]

Supprimer un élément:

delete(set, "item")
8
Denys Séguret

Vous pouvez utiliser une carte et avoir la valeur par exemple un bool

m := map[string] bool {"a":true, "b":true, "x":true}
if m["a"] { // will be false if "a" is not in the map
    //it was in the map
}

Il y a aussi le paquet sort , donc vous pouvez trier et rechercher binaire vos tranches

3
nos