ejemplo - Cómo encontrar si una clave dada existe en un C++ std:: map
multimap c++ (11)
Estoy tratando de verificar si una clave dada está en un mapa y de alguna manera no puedo hacerlo:
typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I''m not sure if equal_range does what I want
cout << p.first;//I''m getting error here
Entonces, ¿cómo puedo imprimir lo que está en p?
Comparando el código de std :: map :: find y std :: map :: count, diría que el primero puede proporcionar alguna ventaja de rendimiento:
const_iterator find(const key_type& _Keyval) const
{ // find an element in nonmutable sequence that matches _Keyval
const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound
return (_Where == end()
|| _DEBUG_LT_PRED(this->_Getcomp(),
_Keyval, this->_Key(_Where._Mynode()))
? end() : _Where);
}
size_type count(const key_type& _Keyval) const
{ // count all elements that match _Keyval
_Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower.
size_type _Num = 0;
_Distance(_Ans.first, _Ans.second, _Num);
return (_Num);
}
Creo que quieres map::find
. Si m.find("f")
es igual a m.end()
, entonces no se encontró la clave. De lo contrario, find devuelve un iterador que apunta al elemento encontrado.
El error se debe a que p.first
es un iterador, que no funciona para la inserción de secuencias. Cambie su última línea a cout << (p.first)->first;
. p
es un par de iteradores, p.first
es un iterador, p.first->first
es la cadena de clave.
Un mapa solo puede tener un elemento para una clave dada, por lo que equal_range
no es muy útil. Se define para el mapa, porque está definido para todos los contenedores asociativos, pero es mucho más interesante para los mapas múltiples.
Para verificar si existe una clave en particular en el mapa, use la función de miembro de count
de una de las siguientes maneras:
m.count(key) > 0
m.count(key) == 1
m.count(key) != 0
La documentation para map::find
dice: "Otra función miembro, map::count
, se puede usar para verificar si existe una clave en particular".
La map::count para map::count
dice: "Dado que todos los elementos en un contenedor de mapas son únicos, la función solo puede devolver 1 (si se encuentra el elemento) o cero (de lo contrario)".
Para recuperar un valor del mapa a través de una clave que sepa que existe, use map::at :
value = m.at(key)
A diferencia de map::operator[] , map::at
no creará una nueva clave en el mapa si la clave especificada no existe.
Puedes usar .find()
:
map<string,string>::iterator i = m.find("f");
if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }
Si quieres comparar par de mapas puedes usar este método:
typedef map<double, double> TestMap;
TestMap testMap;
pair<map<double,double>::iterator,bool> controlMapValues;
controlMapValues= testMap.insert(std::pair<double,double>(x,y));
if (controlMapValues.second == false )
{
TestMap::iterator it;
it = testMap.find(x);
if (it->second == y)
{
cout<<"Given value is already exist in Map"<<endl;
}
}
Esta es una técnica útil.
Tenga cuidado al comparar el resultado del hallazgo con el final como para el mapa ''m'', ya que todas las respuestas se han realizado anteriormente map :: iterator i = m.find ("f");
if (i == m.end())
{
}
else
{
}
no debe intentar realizar ninguna operación, como imprimir la clave o el valor con el iterador i si es igual a m.end (), de lo contrario, se producirá un error de segmentación.
Use map::find
if ( m.find("f") == m.end() ) {
// not found
} else {
// found
}
m.find == m.end() // not found
Si desea utilizar otra API, busque go para m.count(c)>0
if (m.count("f")>0)
cout << " is an element of m./n";
else
cout << " is not an element of m./n";
map <int , char>::iterator itr;
for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++)
{
if (itr->second == ''c'')
{
cout<<itr->first<<endl;
}
}
map<string, string> m;
la clave de verificación existe o no, y devuelve el número de casos (0/1 en el mapa):
int num = m.count("f");
if (num>0) {
//found
} else {
// not found
}
la clave de verificación existe o no, y devuelve iterador:
map<string,string>::iterator mi = m.find("f");
if(mi != m.end()) {
//found
//do something to mi.
} else {
// not found
}
en su pregunta, el error causado por una sobrecarga del operator<<
, porque p.first
es map<string, string>
, no puede imprimirlo. prueba esto:
if(p.first != p.second) {
cout << p.first->first << " " << p.first->second << endl;
}
template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
return (container.find(key) != std::end(container));
}
Por supuesto, si deseaba adquirir una versión más sofisticada, siempre podría crear una plantilla que también tomara una función encontrada y una función no encontrada, algo como esto:
template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction>
void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function)
{
auto& it = container.find(key);
if (it != std::end(container))
{
found_function(key, it->second);
}
else
{
not_found_function(key);
}
}
Y úsalo así:
std::map<int, int> some_map;
find_and_execute(some_map, 1,
[](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; },
[](int key){ std::cout << "key " << key << " not found" << std::endl; });
La desventaja de esto es tener un buen nombre, "find_and_execute" es incómodo y no se me ocurre nada mejor que la parte superior de mi cabeza ...