1. O que é um conjunto
Um conjunto é uma coleção de elementos distintos, sem ordem definida e sem repetição. É um dos conceitos mais básicos da matemática — e também um dos mais próximos do que você já usa todo dia em programação, só que sem o nome formal.
Notação: conjuntos costumam ser escritos com letras maiúsculas, e seus elementos entre chaves. Por exemplo:
A = {1, 2, 3, 4, 5}
B = {2, 4, 6, 8}
Frutas = {"maçã", "banana", "uva"}
Repare: {1, 2, 2, 3} não é um conjunto válido escrito de forma
"limpa" — o 2 repetido não conta duas vezes, o conjunto é o mesmo que {1, 2, 3}.
Conjuntos não têm duplicatas por definição.
2. Notação básica: pertence, subconjunto, e os operadores de conjunto
Cinco símbolos cobrem a maior parte do que você vai precisar:
| Símbolo | Nome | Significado | Exemplo |
|---|---|---|---|
| ∈ | Pertence | o elemento está no conjunto | 3 ∈ A |
| ∉ | Não pertence | o elemento não está no conjunto | 7 ∉ A |
| ⊆ | Subconjunto | todo elemento de um está no outro | {2,4} ⊆ B |
| ∪ | União | todos os elementos dos dois conjuntos juntos, sem repetir | A ∪ B |
| ∩ | Interseção | só os elementos que estão nos dois | A ∩ B |
| − | Diferença | elementos do primeiro que não estão no segundo | A − B |
Usando os conjuntos definidos acima (A = {1,2,3,4,5} e B = {2,4,6,8}):
A ∪ B = {1, 2, 3, 4, 5, 6, 8} (junta tudo, sem repetir)
A ∩ B = {2, 4} (só o que está nos dois)
A − B = {1, 3, 5} (só o que é exclusivo de A)
2 ∈ A (verdadeiro)
7 ∈ A (falso)
3. Visualizando com diagramas de Venn
O jeito clássico de visualizar relações entre conjuntos é o diagrama de Venn: cada conjunto é um círculo, e a posição relativa dos círculos mostra o que é compartilhado.
Fig. 1 — Diagrama de Venn de A = {1,2,3,4,5} e B = {2,4,6,8}. A região central (2, 4) é a interseção.
Se você já usou um objeto Set em JavaScript ou
HashSet<T> em C#, você já trabalhou com conjuntos na
prática — coleções sem elementos duplicados. Métodos como filtrar itens em comum entre
duas listas, ou remover duplicatas com new Set(array), são
operações de conjunto disfarçadas.
4. Conjuntos como base de arrays, listas e (mais à frente) LINQ
Um array ou lista em programação é, na prática, uma coleção ordenada — a diferença de um conjunto matemático puro é que arrays permitem repetição e têm posição definida (índice). Ainda assim, a teoria de conjuntos é a fundação conceitual por trás de praticamente toda operação de coleção que você vai usar:
- União ≈ combinar duas listas removendo duplicatas.
- Interseção ≈ encontrar itens presentes em ambas as listas.
- Diferença ≈ itens de uma lista que não aparecem na outra.
- Subconjunto ≈ verificar se todos os itens de uma coleção existem em outra.
No módulo seguinte deste curso, quando você aprender LINQ em C# (e o equivalente conceitual
já existe em métodos de array do JavaScript como filter,
some, every), vai reconhecer esses
mesmos quatro conceitos por trás de métodos como .Union(),
.Intersect() e .Except().
5. Relações: conectando elementos de dois conjuntos
Uma relação entre um conjunto A e um conjunto B é, formalmente, qualquer
conjunto de pares ordenados (a, b) onde a ∈ A
e b ∈ B. Em outras palavras: uma relação é uma regra de
associação entre elementos — e essa regra pode ser bagunçada. Um mesmo a
pode se relacionar com vários b diferentes, e vice-versa.
Exemplo: seja A o conjunto de alunos e B o conjunto de disciplinas. "Está matriculado em" é uma relação — um aluno pode estar matriculado em várias disciplinas, e uma disciplina pode ter vários alunos. Isso é exatamente uma relação muitos-para-muitos, o mesmo conceito usado em banco de dados relacional.
6. Funções: o caso especial que vira código
Uma função é uma relação especial, com uma regra extra e muito importante: cada elemento do domínio (entrada) se conecta a exatamente um elemento do contradomínio (saída) — nunca zero, nunca dois ou mais.
Formalmente: uma função f: A → B associa a cada
a ∈ A exatamente um b ∈ B, escrito
f(a) = b. A é o domínio (todas as
entradas válidas), B é o contradomínio (onde as saídas vivem).
Essa restrição de "exatamente uma saída por entrada" é o motivo de f(x) = x²
ser uma função (todo número tem um único quadrado), mas "a raiz quadrada de x, considerando
positiva e negativa" não ser — teria duas saídas para uma entrada, o que
quebra a definição.
f: ℝ → ℝ
f(x) = x² + 1
f(2) = 5
f(3) = 10
f(-2) = 5
function f(x) {
return x * x + 1;
}
f(2); // 5
f(3); // 10
f(-2); // 5
É a mesma estrutura, literalmente: um nome, um domínio de entradas aceitas (os parâmetros e
seus tipos), e uma regra que produz exatamente uma saída (o return).
Uma função de programação que às vezes retorna um número e às vezes retorna
undefined para a mesma entrada, ou que depende de uma variável
global escondida para decidir o resultado, está quebrando essa garantia matemática — e é
exatamente esse tipo de função que costuma ser mais difícil de testar e depurar.
Uma função pura (o termo que você provavelmente já ouviu em contextos de programação funcional) é justamente uma função de programação que se comporta como uma função matemática de verdade: a mesma entrada sempre produz a mesma saída, sem efeitos colaterais escondidos. Isso não é jargão vazio — é a definição matemática de função sendo levada a sério.