1. Algoritmos de Consulta (Não Modificadores)
Estes algoritmos realizam operações de leitura sobre os containers sem alterar o estado ou a ordem dos elementos originais.
1.1 find e find_if
Utilizados para localizar elementos específicos ou que atendam a um critério lógico (predicado).
#include <algorithm>
#include <vector>
#include <iostream>
std::vector<int> dados = {10, 25, 40, 55, 70};
// Busca por valor exato
auto it = std::find(dados.begin(), dados.end(), 40);
if (it != dados.end()) {
std::cout << "Valor encontrado: " << *it << std::endl;
}
// Busca baseada em condição (primeiro valor par)
auto it_par = std::find_if(dados.begin(), dados.end(), [](int n) {
return n % 2 == 0;
});
if (it_par != dados.end()) {
std::cout << "Primeiro par: " << *it_par << std::endl;
}
1.2 count e count_if
Servem para quantificar a ocorrência de elementos no intervalo.
std::vector<int> notas = {7, 5, 8, 7, 9, 7};
// Conta quantas vezes o número 7 aparece
long qtd_sete = std::count(notas.begin(), notas.end(), 7);
// Conta elementos maiores que 6
long aprovados = std::count_if(notas.begin(), notas.end(), [](int n) {
return n > 6;
});
1.3 Verificadores Lógicos: all_of, any_of e none_of
Validam propriedades sobre toda a coleção de forma booleana.
std::vector<int> valores = {2, 4, 6, 8};
bool todos_pares = std::all_of(valores.begin(), valores.end(), [](int x) { return x % 2 == 0; });
bool algum_impar = std::any_of(valores.begin(), valores.end(), [](int x) { return x % 2 != 0; });
bool nenhum_negativo = std::none_of(valores.begin(), valores.end(), [](int x) { return x < 0; });
2. Algoritmos de Modificação de Sequência
Estas funções alteram o conteúdo dos containers, seja movendo, copiando ou transformando elementos.
2.1 transform
Aplica uma operação em cada elemento e armazena o resultado em um novo destino (ou no próprio container).
std::vector<int> entrada = {1, 2, 3, 4};
std::vector<int> dobro;
// Multiplica cada elemento por 2 e insere em 'dobro'
std::transform(entrada.begin(), entrada.end(), std::back_inserter(dobro), [](int n) {
return n * 2;
});
2.2 O Idioma Erase-Remove
O algoritmo std::remove não altera o tamanho do container; ele apenas desloca os elementos indesejados para o final. Para deletá-los fisicamente, deve-se usar o método erase do container.
std::vector<int> lista = {1, 2, 99, 3, 99, 4};
// Remove logicamente o valor 99
auto novo_fim = std::remove(lista.begin(), lista.end(), 99);
// Remove fisicamente do vector
lista.erase(novo_fim, lista.end());
// Resultado: {1, 2, 3, 4}
2.3 replace e replace_if
std::vector<int> seq = {10, 20, 30, 20};
// Substitui 20 por 100
std::replace(seq.begin(), seq.end(), 20, 100);
// Substitui valores menores que 50 por zero
std::replace_if(seq.begin(), seq.end(), [](int n) { return n < 50; }, 0);
3. Ordenação e Busca Binária
Para alta performance em buscas, a ordenação é um pré-requisito fundamental.
3.1 sort e stable_sort
std::vector<int> itens = {5, 1, 9, 3, 7};
// Ordenação padrão (geralmente Introsort)
std::sort(itens.begin(), itens.end());
// Ordenação estável (preserva ordem de elementos iguais)
std::stable_sort(itens.begin(), itens.end(), std::greater<int>()); // Ordem decrescente
3.2 Pesquisa em Coleções Ordenadas
std::vector<int> ordenado = {10, 20, 20, 30, 40};
// Verifica existência (O(log n))
bool existe = std::binary_search(ordenado.begin(), ordenado.end(), 20);
// Encontra o primeiro elemento que não é menor que 20
auto lb = std::lower_bound(ordenado.begin(), ordenado.end(), 20);
// Encontra o primeiro elemento maior que 20
auto ub = std::upper_bound(ordenado.begin(), ordenado.end(), 20);
4. Algoritmos Numéricos
Localizados no header <numeric>, são essenciais para cálculos matemáticos em sequências.
4.1 accumulate e iota
#include <numeric>
std::vector<int> serie(5);
// Preenche com 1, 2, 3, 4, 5
std::iota(serie.begin(), serie.end(), 1);
// Soma total dos elementos
int soma = std::accumulate(serie.begin(), serie.end(), 0);
// Produto total dos elementos
int produto = std::accumulate(serie.begin(), serie.end(), 1, std::multiplies<int>());
5. Manipulação de Heaps e Extremos
A STL permite tratar vetores como estruturas de dados Heap (Max-Heap por padrão).
std::vector<int> v = {3, 1, 4, 1, 5, 9};
std::make_heap(v.begin(), v.end()); // Transforma em heap
std::pop_heap(v.begin(), v.end()); // Move o maior para o fim
int maior = v.back();
v.pop_back(); // Remove o elemento
// Encontrar extremos sem ordenar
auto [min, max] = std::minmax_element(v.begin(), v.end());
std::cout << "Min: " << *min << " Max: " << *max;
6. Operações de Conjunto
Trabalham com intervalos ordenados para realizar operações matemáticas de conjuntos.
std::vector<int> conjunto1 = {1, 2, 3};
std::vector<int> conjunto2 = {2, 3, 4};
std::vector<int> resultado;
// Interseção: {2, 3}
std::set_intersection(conjunto1.begin(), conjunto1.end(),
conjunto2.begin(), conjunto2.end(),
std::back_inserter(resultado));