Explorer les opérations de HashSet en Rust

RustRustBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, nous explorons les fonctionnalités de la structure de données HashSet en Rust, qui garantit des éléments uniques et peut effectuer des opérations telles que l'union, la différence, l'intersection et la différence symétrique sur des ensembles.

Note : Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/boolean_type("Boolean Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/mutable_variables -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/integer_types -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/boolean_type -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/function_syntax -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/expressions_statements -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/lifetime_specifiers -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/method_syntax -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} rust/operator_overloading -.-> lab-99262{{"Explorer les opérations de HashSet en Rust"}} end

HashSet

Considérez un HashSet comme un HashMap où nous ne nous intéressons qu'aux clés (HashSet<T> est, en réalité, simplement un wrapper autour de HashMap<T, ()>).

"Pourquoi faire ça?" vous demandez. "Je pourrais tout simplement stocker les clés dans un Vec."

La caractéristique unique d'un HashSet est qu'il est garanti de ne pas avoir d'éléments dupliqués. C'est le contrat que toute collection d'ensemble remplit. HashSet n'est qu'une implémentation. (voir également : BTreeSet)

Si vous insérez une valeur qui est déjà présente dans le HashSet (c'est-à-dire que la nouvelle valeur est égale à l'existante et qu'elles ont toutes les deux le même hachage), alors la nouvelle valeur remplacera l'ancienne.

Cela est très pratique lorsque vous ne voulez jamais avoir plus d'un exemplaire de quelque chose, ou lorsque vous voulez savoir si vous avez déjà quelque chose.

Mais les ensembles peuvent faire bien plus que ça.

Les ensembles ont 4 opérations principales (tous les appels suivants renvoient un itérateur) :

  • union : obtenir tous les éléments uniques des deux ensembles.

  • difference : obtenir tous les éléments qui sont dans le premier ensemble mais pas dans le second.

  • intersection : obtenir tous les éléments qui ne sont que dans les deux ensembles.

  • symmetric_difference : obtenir tous les éléments qui sont dans un ensemble ou dans l'autre, mais pas dans les deux.

Essayez toutes ces opérations dans l'exemple suivant :

use std::collections::HashSet;

fn main() {
    let mut a: HashSet<i32> = vec![1i32, 2, 3].into_iter().collect();
    let mut b: HashSet<i32> = vec![2i32, 3, 4].into_iter().collect();

    assert!(a.insert(4));
    assert!(a.contains(&4));

    // `HashSet::insert()` renvoie false si
    // une valeur était déjà présente.
    assert!(b.insert(4), "Value 4 is already in set B!");
    // FIXME ^ Commenter cette ligne

    b.insert(5);

    // Si le type d'élément d'une collection implémente `Debug`,
    // alors la collection implémente `Debug`.
    // Elle imprime généralement ses éléments au format `[elem1, elem2,...]`
    println!("A: {:?}", a);
    println!("B: {:?}", b);

    // Affiche [1, 2, 3, 4, 5] dans un ordre arbitraire
    println!("Union: {:?}", a.union(&b).collect::<Vec<&i32>>());

    // Cela devrait afficher [1]
    println!("Difference: {:?}", a.difference(&b).collect::<Vec<&i32>>());

    // Affiche [2, 3, 4] dans un ordre arbitraire.
    println!("Intersection: {:?}", a.intersection(&b).collect::<Vec<&i32>>());

    // Affiche [1, 5]
    println!("Symmetric Difference: {:?}",
             a.symmetric_difference(&b).collect::<Vec<&i32>>());
}

(Les exemples sont adaptés de la documentation.)

Résumé

Félicitations ! Vous avez terminé le laboratoire HashSet. Vous pouvez pratiquer d'autres laboratoires dans LabEx pour améliorer vos compétences.