Explorando as Operações do Conjunto HashSet em Rust

Beginner

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

Introdução

Neste laboratório, exploramos as funcionalidades da estrutura de dados HashSet em Rust, que garante elementos únicos e permite operações como união, diferença, interseção e diferença simétrica em conjuntos.

Nota: Se o laboratório não especificar um nome de arquivo, você pode usar qualquer nome de arquivo que desejar. Por exemplo, você pode usar main.rs, compilar e executar com rustc main.rs && ./main.

HashSet

Considere um HashSet como um HashMap onde nos importamos apenas com as chaves (um HashSet<T> é, na realidade, apenas um invólucro em torno de HashMap<T, ()>).

"Qual o objetivo disso?", você pergunta. "Eu poderia simplesmente armazenar as chaves em um Vec."

A característica única de um HashSet é que ele garante que não tenha elementos duplicados. Esse é o contrato que qualquer coleção de conjuntos cumpre. HashSet é apenas uma implementação. (veja também: BTreeSet)

Se você inserir um valor que já está presente no HashSet (ou seja, o novo valor é igual ao existente e ambos têm o mesmo hash), o novo valor substituirá o antigo.

Isso é ótimo quando você nunca quer mais de um de algo, ou quando quer saber se já tem algo.

Mas os conjuntos podem fazer mais do que isso.

Os conjuntos têm 4 operações principais (todas as chamadas a seguir retornam um iterador):

  • union: obter todos os elementos únicos em ambos os conjuntos.

  • difference: obter todos os elementos que estão no primeiro conjunto, mas não no segundo.

  • intersection: obter todos os elementos que estão apenas em ambos os conjuntos.

  • symmetric_difference: obter todos os elementos que estão em um conjunto ou no outro, mas não em ambos.

Experimente todas essas operações no exemplo a seguir:

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()` retorna false se
    // já houver um valor presente.
    assert!(b.insert(4), "O valor 4 já está no conjunto B!");
    // FIXME ^ Comente esta linha

    b.insert(5);

    // Se o tipo de elemento de uma coleção implementar `Debug`,
    // então a coleção implementa `Debug`.
    // Normalmente, imprime seus elementos no formato `[elem1, elem2, ...]`
    println!("A: {:?}", a);
    println!("B: {:?}", b);

    // Imprime [1, 2, 3, 4, 5] em uma ordem arbitrária
    println!("União: {:?}", a.union(&b).collect::<Vec<&i32>>());

    // Isso deve imprimir [1]
    println!("Diferença: {:?}", a.difference(&b).collect::<Vec<&i32>>());

    // Imprime [2, 3, 4] em uma ordem arbitrária.
    println!("Interseção: {:?}", a.intersection(&b).collect::<Vec<&i32>>());

    // Imprime [1, 5]
    println!("Diferença Simétrica: {:?}",
             a.symmetric_difference(&b).collect::<Vec<&i32>>());
}

(Os exemplos foram adaptados da documentação.)

Resumo

Parabéns! Você concluiu o laboratório HashSet. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.