Map de string em C++
Autor: Ruy Minoru Ito Takata | Publicado: 2011-11-03T10:57:00-02:00

Uma das grandes vantagens de programar em C++ ao invés de C é a utilização da STL (Standard Template Library). Ela disponibiliza Containers, Iterators, Algoritmos e Funções Objetos. Nesse post irei abordar uma característica de busca no container MAP e MULTIMAP.

Container são objetos que armazenam outros objetos e o método de acessar esses objetos. Por exemplo, posso contruir um vetor de inteiros (vector&lt;int&gt; v). Qual a vantagem de utilizar um vector ao invés de criar um elemento do tipo int v[10]? Se você reparar, verá que na declaração do vector eu não especifiquei o tamanho. Isso mesmo, ele é auto dimensionável. Ele também tem algumas funções que facilitam a manipulação de seus elementos.

Outra coisa muito interessante que C++ tem é a classe string. A classe string é um container de char's, que tem algumas funções que facilitam a manipulação dos elementos. Também é auto redimensionável.

Os containers MAP e MULTIMAP são containers associativos com 2 elementos, uma chave e um dado. A diferença é que no map, a chave é única, e no multimap, a chave pode se repetir. A construção básica de um map seria map&lt;int, string&gt; m, onde o primeiro elemento é a chave.

É possível acessar o elemento através de sua chave, por exemplo, tenho um map com os seguintes pares: 1, primeiro; 2, segundo; 3, terceiro; 4, quarto. A função m.find(3) irá retornar um iterator (que deve ser declarado como map&lt;int, string&gt; it, por exemplo) que aponta para o elemento de chave 3. Para acessar o dado, eu faria string elemento = (*it).second.

Mas e se a chave for uma string (map&lt;string, string&gt; mstring), a busca será case sensitive. Para realizar busca case insensitive é preciso implementar o método de busca, e ele deve ser especificado na declaração da variável.

No caso, eu criei um utils.h com o seguinte código:

#ifndef UTILS_H
#define UTILS_H
#include &lt;string&gt;
#include &lt;algorithm&gt;
using namespace std;
struct ltstr
{&nbsp; &nbsp; bool operator()(string s1, string s2) const
&nbsp; &nbsp;&nbsp;{
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;string s1Tmp, s2Tmp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;s1Tmp = s1;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;s2Tmp = s2;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;transform(s1Tmp.begin(), s1Tmp.end(), s1Tmp.begin(), ::toupper);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;transform(s2Tmp.begin(), s2Tmp.end(), s2Tmp.begin(), ::toupper);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;return s1Tmp.compare(s2Tmp) &lt; 0;&nbsp; &nbsp;&nbsp;}
};
#endif // UTILS_H
Para declarar a variável map basta fazer como abaixo:


#include &lt;map&gt;
#include &lt;string&gt;
#include "utils.h"
#include &lt;iostream&gt;
using namespace std;
int main()
{
&nbsp; &nbsp;&nbsp;map&lt;string, string, ltstr&gt; mstring;
&nbsp; &nbsp;&nbsp;map&lt;string, string, ltstr&gt;::iterator it;
&nbsp; &nbsp;&nbsp;mstring.insert(pair&lt;string, string&gt;("a", "primeiro"));
&nbsp; &nbsp;&nbsp;mstring.insert(pair&lt;string, string&gt;("b", "segundo"));
&nbsp; &nbsp;&nbsp;mstring.insert(pair&lt;string, string&gt;("c", "terceiro"));
&nbsp; &nbsp;&nbsp;mstring.insert(pair&lt;string, string&gt;("D", "quarto"));
&nbsp; &nbsp;&nbsp;mstring.insert(pair&lt;string, string&gt;("e", "quinto"));
&nbsp; &nbsp;&nbsp;it = mstring.find("d");
&nbsp; &nbsp;&nbsp;if (it != mstring.end())
&nbsp; &nbsp;&nbsp;{
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;cout &lt;&lt; "elemento procurado: " &lt;&lt; (*it).second.c_str() &lt;&lt; endl;&nbsp; &nbsp;&nbsp;}
&nbsp; &nbsp;&nbsp;return 0;
}
<!--EndFragment-->

Essa solução funciona também para o elemento multimap.