Além dos contêineres sequenciais que foram introduzidos no C++ (vector, array, deque etc.) como alternativa aos arrays estáticos ou alocados com new
, também foram adicionados à linguagem os contêineres associativos, entre os quais está o map. Mas afinal de contas, o que é o map em C++? Vejamos a seguir as suas 4 características principais.
- Os maps associam uma chave única a um valor mapeado;
- As chaves em um map são ordenadas usando o operador < do seu tipo;
- Map fornece acesso em tempo constante a seus elementos (O(1));
- Os elementos de um map são do tipo pair.
Map – definição
O map é um contêiner associativo que liga uma chave única a um valor que lhe é correspondente (esse valor é chamado de valor mapeado, e seu tipo é o tipo mapeado); esta chave pode ser de diversos tipos, sendo o string o mais comum dentre eles. Além disso, as chaves de um map são ordenadas usando o operador < do tipo da chave (em ordem crescente, se as chavem forem números, por exemplo).
Como usar o map em C++?
O map é um contêiner template, e portanto, assim como o vector é preciso indicar quais são os tipos de ambos sua chave e do valor armazenado em cada entrada. Além disso, map é um tipo da biblioteca padrão, definido no namespace std, no header <map>. A sintaxe usada é a seguinte:
Map – Sintaxe
std::map<tipo-da-chave, tipo-do-valor-mapeado> nome-do-mapa;
O tipo map em C++ é útil quando se deseja armazenar valores associados a uma chave única, e quando se deseja ter a capacidade de recuperar esses valores a qualquer momento com um custo computacional pequeno (o acesso aos elementos de um map em C++ é feito em tempo constante – O(1)). Um exemplo de emprego dos maps é a contagem do número de aparições de um determinado valor em uma lista, por exemplo.
Exemplo de uso de Map em C++
Vejamos a seguir um exemplo de utilização de um map em C++ para guardar notas de alunos usando seus nomes como chaves (Bloco de código do exemplo #1). Começamos criando um map de strings para unsigned ints (linha 11) chamado aStudentsGradesMap
, que guarda nas suas chaves o nome dos alunos de uma turma, e nos valores correspondentes a nota de cada aluno. Note como o map é inicializado: usa-se um primeiro par de chaves ( { } ), e dentro dele há outros pares de chaves, um para cada elemento inserido no map – cada um desses pares internos cria um objeto de tipo std::pair<const string, usigned int>, que é o verdadeiro tipo dos elementos de um map.
Map e Pair
Os verdadeiros elementos armazenados em um map em C++ são os pairs. O pair é um tipo de biblioteca padrão definido no header <utility> que possui dois membros públicos: first e second (correspondentes ao primeiro e ao segundo elementos do pair, respectivamente). Em um map, o pair (que também é um template) tem os mesmo tipos que o map, ou seja, em um map<string, int>, os elementos são do tipo pair<string, int>.
Além disso, como podemos ver no resultado do exemplo #1, ao imprimir os elementos do map, eles são obtidos em ordem alfabética das chaves. Isso acontece porque os elementos de um map são ordenados usando o operador < do tipo de dado da sua chave (como mencionei na definição de map). Um outro ponto importante é que, ao inicializar os elementos dos alunos Carla e Diego, suas notas (8.0 e 7.7) são truncadas porque o tipo dos dados mapeados é unsigned int.
Em seguida, removemos o elemento correspondente ao aluno Marcos do map (linha 21) usando a função erase, que remove um elemento do map a partir de sua chave. Adicionamos, logo adiante (linha 23), um novo aluno ao map: Enzo, com nota 5. Para fazê-lo, usamos o operador [], que permite acessar um elemento de um mapa através de sua chave, mas também permtie criar um novo elemento no mapa se a chave fornecida não existir nele. Há outras formas de se adicionar elementos a um map em C++, semelhantes aos modos de se adicionar valores a um vetor, através dos métodos insert, emplace etc.
Por fim, usamos a função find do tipo map em C++ que permite recuperar um iterador que aponta para o elemento correspondente à chave fornecida como argumento, ou o iterador retornado por end()
caso a chave não esteja presente no map. Usamo-la para buscar o aluno Marcos, mas como ele foi expulso da escola, não o encontramos mais (seu elemento foi removido do mapa na linha 21).
/*************************************** * O que é Map em C++? * Exemplo #1 - Uso de Map, find e erase ***************************************/ #include <iostream> #include <map> using namespace std; int main() { std::map<const string, unsigned int> aStudentsGradesMap = {{"João", 9}, {"Maria", 10}, {"Diego", 7.7}, {"Carla", 8.0}, {"Marcos", 0}}; // Nota que as chaves dos elementos de um map são sempre const for (const std::pair<const string, unsigned int>& aStudentGradePair : aStudentsGradesMap) { // first guarda o nome do aluno, e second guarda sua nota cout << "Aluno(a)/Nota: " << aStudentGradePair.first << ", " << aStudentGradePair.second << endl; } // Remoção do elemento cuja chave é Marcos do map aStudentsGradesMap.erase("Marcos"); // Adição de um novo elemento com chave Enzo e valor mapeado 5 ao map aStudentsGradesMap["Enzo"] = 5; cout << "\n-----------------------------------" << endl; cout << "Marcos foi expulso do colégio :(" << endl; cout << "Enzo foi matriculado do colégio :)" << endl; cout << "\n-----------------------------------" << endl; cout << "Alunos matriculados:" << endl; // Forma equivalente de se usar o for com map em C++. // O auto torna a declaração da variável do loop muito mais concisa. for (const auto& aStudentGradePair : aStudentsGradesMap) { cout << aStudentGradePair.first << endl; } cout << "\n-----------------------------------" << endl; if (aStudentsGradesMap.find("Marcos") == aStudentsGradesMap.end()) { cout << "Onde está Marcos?" << endl; } return 0; }
Conclusão
Neste artigo, vimos o que são os maps em C++, qual é a sintaxe a se utilizar para se criar um map, e também algumas funções de manipulação fornecidas por esse tipo (erase, find e o operador [ ]). Vimos que as três principais características dos maps são as seguintes:
- Os maps associam uma chave única a um valor mapeado;
- As chaves em um map são ordenadas usando o operador < do seu tipo;
- Map fornece acesso em tempo constante a seus elementos (O(1));
- Os elementos de um map são do tipo pair.
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.