Como fazer busca em vetor em C++: 2 métodos muito fáceis

Busca em vetor em C++

Se você quiser fazer uma busca em vetor em C++, e já esteja escrevendo um for para realizar essa tarefa, pare agora mesmo! No C++, felizmente, não é preciso reinventar a roda: a própria biblioteca padrão fornece a função find() que permite fazer precisamente isso.

Para buscar um elemento em um vetor em C++, basta usar o método std::find() com dois iteradores, um para o início da sequência na qual se quer encontrar o elemento e outro para o fim da sequência, e o valor que se deseje encontrar. Como exemplo, para encontrar o valor 5 num vetor chamado x, fazemos std::find(begin(x), end(x), 5).

O retorno do método find é um iterador que se comporta assim:

  • Se o valor for encontrado na sequência percorrida pelo find, o iterador aponta para esse valor no vetor;
  • Se o valor não for encontrado na sequência, o iterador aponta será igual ao iterador end do vetor (ou seja, ele aponta para uma posição após o último elemento do vetor).

Vejamos abaixo um exemplo do uso do find para encontrar o valor 7 em um vetor de inteiros chamado numbers.


Exemplo 1 – std::find com um vetor de inteiros

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    const vector<int> numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    const int x {7};
    
    auto it = std::find(begin(numbers), end(numbers), x);
    
    if (it != end(numbers)) {
        cout << "Valor encontrado: " << *it << endl;
    } else {
        cout << "Valor " << x << " não existe no vetor numbers" << endl;
    }
    
    return 0;
}

Valor encontrado: 7


Vemos no exemplo 1 que eu defini uma variável chamada it para armazenador o iterador de retorno do método find (é comum nomear iteradores it, de iterador). Na linha 14, eu verifiquei no if se it era diferente de end(numbers), que é o iterador que aponta para uma posição além do último elemento do vetor. Por que isso?

Fiz essa verificação porque quando se faz uma busca em vetor em C++ usando find e o valor procurado não é encontrado, o retorno do find é o iterador end do vetor em questão. Assim, se o valor de retorno do find for diferente do iterador end, isso significa que o elemento que buscamos foi encontrado no nosso vetor.

Busca em vetor em C++ com find_if

O segundo método usado para se buscar um valor em um vetor em C++ é o find_if. Ele funciona da mesma maneira que o find, recebendo dois iteradores que apontam para o início e para o final da sequência de entrada, respectivamente, mas o seu terceiro parâmetro é diferente, e é aí que está o segredo.

O terceiro parâmetro do find_if é chamado de predicado, e ele nada mais é que uma função que recebe um único parâmetro e retorna true ou false, dependendo do resultado de algum teste que a função realize.

Como funciona o find_if?

O find_if percorre a sequência que lhe é fornecida na entrada, e aplica o predicado a cada um dos seus elementos. O retorno do find_if será um iterador que aponta para o primeiro elemento para o qual o predicate retorne true. Se o predicado não retornar true para nenhum elemento, o retorno do find_if será o iterador end da sequência de entrada.

Vejamos a seguir um exemplo do uso do find_if para encontrar o primeiro elemento ímpar em um vetor de inteiros.


Exemplo 2 – std::find_if com um vetor de inteiros e função lambda

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    const vector<int> numbers {2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // função lambda que detecta números ímpares
    auto isOdd = [](const int i) {return i % 2 != 0;};
    
    if (auto it = std::find_if(begin(numbers), end(numbers), isOdd); it != end(numbers)) {
        cout << "Primeiro valor ímpar encontrado: " << *it << endl;
    } else {
        cout << "Nenhum valor ímpar no vetor numbers." << endl;
    }

    return 0;
}

Primeiro valor impar encontrado: 3


Vemos no exemplo 2 que o predicado usado para testar os elementos do meu vetor numbers se chama isOdd, e ele é uma função lambda. As funções lambda serão o assunto de um outro artigo, mas aqui basta saber que elas permitem definir uma função de maneira rápida e concisa, e armazená-la em uma variável qualquer. Para invocar uma função lambda, basta usar-lhe o operador() como em isOdd(5) e voilà!

Note que eu utilizei o campo de inicialização do if para obter o iterador resultante do find_if, e em seguida verifiquei se esse iterador era diferente do iterador end, o que significa que ao menos um valor ímpar foi encontrado no meu vetor numbers. Como vemos na saída, o find_if encontrou por primeiro o número 3 usando o predicado isOdd, e me retornou um iterador que aponta para esse elemento do vetor.

Próximos passos

Agora que sabemos como encontrar um elemento em um vetor, seja através da busca direta (std::find), ou através da busca utilizando um predicado (std::find_if), é importante saber como encontrar todos os elementos de um vetor que satisfazem uma condição qualquer. Escreverei logo mais um artigo sobre isso, mas até lá aconselho que vocês dêem uma olhada no artigo sobre a palavra-chave auto em C++. Até mais!

Gostou do artigo? Então inscreva-se na nossa newsletter para não perder nenhum dos nossos artigos 🙂

Foto de perfil de Emanoel

Sou apaixonado por tecnologia, literatura e também filosofia. O cultivo dessas paixões ao longo da minha trajetória me inspiraram a compartilhar aquilo que aprendo com os outros da maneira mais clara que eu possa. Sou formado em Engenharia Elétrica no Brasil, e também sou engenheiro formado na França. Trabalho atualmente como programador C++ em uma multinacional francesa, uma das maiores empresas de TI do mundo.

Leave a Reply

Your email address will not be published. Required fields are marked *