Médio Rust
Contagem de frequência com entry API
Enunciado
Dada a frase "a b a c b a", conte quantas vezes cada palavra aparece usando um HashMap e a entry API. Imprima cada palavra e sua contagem em ordem alfabética.
Requisitos
- Separar a frase com
split_whitespace(). - Usar
entry(...).or_insert(0)para contar. - Coletar os pares em um
Vece ordenar por chave antes de imprimir.
Código inicial
use std::collections::HashMap;
fn main() {
let frase = "a b a c b a";
// TODO: conte as palavras e imprima em ordem alfabética
}
Saída esperada
a: 3
b: 2
c: 1
Ver dica
Para ordenar, colete contagem.iter() em um Vec de tuplas e use .sort_by_key(|(k, _)| *k).
Mostrar solução
use std::collections::HashMap;
fn main() {
let frase = "a b a c b a";
// HashMap que associa &str a u32
let mut contagem: HashMap<&str, u32> = HashMap::new();
// Itera pelas palavras separadas por espaços
for palavra in frase.split_whitespace() {
// entry: se não existir, insere 0; depois incrementa
*contagem.entry(palavra).or_insert(0) += 1;
}
// Coleta em Vec para poder ordenar (HashMap não tem ordem)
let mut pares: Vec<(&str, u32)> = contagem.into_iter().collect();
pares.sort_by_key(|(palavra, _)| *palavra);
for (palavra, qtd) in &pares {
println!("{}: {}", palavra, qtd);
}
}
Passo a passo
let mut contagem: HashMap<&str, u32> = HashMap::new();cria o mapa com chaves&str(fatias da frase) e valoresu32.frase.split_whitespace()gera um iterador de palavras, ignorando espaços múltiplos.contagem.entry(palavra).or_insert(0)busca a chave; se não existir, insere0e devolve&mut u32para o valor.*... += 1desreferencia a referência mutável e incrementa a contagem. Isso evita duas buscas no mapa.contagem.into_iter().collect()consome o mapa e cria umVecde tuplas(&str, u32). Agora podemos ordenar.pares.sort_by_key(|(palavra, _)| *palavra)ordena alfabeticamente pela chave.- O
forfinal imprime cada par no formato pedido.
Por que funciona
A entry API resolve o padrão "inserir se ausente, depois atualizar" em uma única chamada, sem precisar de get seguido de insert. Como o HashMap não mantém ordem, coletamos em Vec e ordenamos — uma combinação muito comum em Rust.
Erros comuns
- Tentar
contagem[palavra] += 1sem a chave existir: causa panic em tempo de execução (índice inexistente). - Usar
contagem.get(palavra)e depoisinsert: compila, mas faz duas buscas e pode dar erro de empréstimo se misturar referências. - Iterar diretamente sobre
contagemsem coletar e esperar ordem alfabética: a ordem é arbitrária e o teste falha.
Outra forma de resolver
Se não precisar de ordenação, basta iterar o mapa:
for (palavra, qtd) in &contagem {
println!("{}: {}", palavra, qtd);
}
É mais curto, mas a ordem de saída não é garantida.
Saída esperada
a: 3
b: 2
c: 1