Desafio C#
Interseção de conjuntos com Dictionary e HashSet
Enunciado
Dados dois arrays de strings, encontre os elementos comuns a ambos. Use um HashSet<string> para o primeiro array e um Dictionary<string, int> para contar quantas vezes cada elemento aparece no segundo array. Imprima os elementos comuns e suas contagens no segundo array, ordenados alfabeticamente.
Requisitos
- Usar
HashSet<string>para armazenar os elementos do primeiro array. - Usar
Dictionary<string, int>para contar as ocorrências no segundo array. - Imprimir apenas os elementos que estão em ambos, no formato
elemento: contagem. - Ordenar a saída alfabeticamente pelo elemento.
Código inicial
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
string[] array1 = { "apple", "banana", "orange", "grape" };
string[] array2 = { "banana", "apple", "apple", "kiwi", "orange", "banana" };
// Seu código aqui
}
}
Saída esperada
apple: 2
banana: 2
orange: 1
Ver dica
Primeiro, crie um HashSet<string> com os elementos de array1. Depois, percorra array2 e use TryGetValue para atualizar a contagem no dicionário. Por fim, filtre os elementos que estão no conjunto e ordene.
Mostrar solução
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
string[] array1 = { "apple", "banana", "orange", "grape" };
string[] array2 = { "banana", "apple", "apple", "kiwi", "orange", "banana" };
// Conjunto com os elementos do primeiro array
var conjunto1 = new HashSet<string>(array1);
// Dicionário para contar ocorrências no segundo array
var contagens = new Dictionary<string, int>();
foreach (string item in array2)
{
contagens.TryGetValue(item, out int atual);
contagens[item] = atual + 1;
}
// Filtra os elementos que estão no conjunto1 e ordena alfabeticamente
var comuns = contagens
.Where(par => conjunto1.Contains(par.Key))
.OrderBy(par => par.Key);
foreach (var par in comuns)
{
Console.WriteLine($"{par.Key}: {par.Value}");
}
}
}
Passo a passo
- Criamos um
HashSet<string>a partir doarray1para consultas rápidas de pertinência. - Criamos um
Dictionary<string, int>para contar quantas vezes cada string aparece noarray2. - Iteramos sobre
array2; para cada item, usamosTryGetValuepara obter a contagem atual (0 se não existir) e atualizamos o dicionário. - Usamos LINQ para filtrar os pares cuja chave está no
conjunto1e ordenamos por chave comOrderBy. - Imprimimos cada par no formato
chave: valor.
Por que funciona
O HashSet permite verificar se um elemento está no primeiro array em tempo O(1). O Dictionary acumula as contagens do segundo array também em O(1) por elemento. A combinação das duas estruturas resolve o problema de forma eficiente, sem loops aninhados. A ordenação final garante a saída esperada.
Erros comuns
- Não usar
TryGetValue: tentar acessarcontagens[item]diretamente lança exceção se a chave não existir. UseTryGetValueouGetValueOrDefault. - Esquecer de filtrar pelo conjunto: se apenas imprimir todas as contagens, aparecerão elementos que não estão no
array1(ex.: "kiwi"). - Ordenar antes de filtrar: a ordem não afeta o filtro, mas é mais eficiente filtrar primeiro e ordenar depois.
- Modificar a coleção durante a iteração: não modifique
contagensenquanto itera sobre ela; aqui criamos uma nova sequência com LINQ.
Outra forma de resolver
Poderia usar array1.Intersect(array2) para obter os comuns, mas precisaríamos contar as ocorrências separadamente. A abordagem com HashSet e Dictionary é mais explícita e eficiente para contagens.
Saída esperada
apple: 2
banana: 2
orange: 1