mapa example ejemplo clase c++ iterator find stdmap

example - El valor de comprobación existe en std:: map-C++



multimap c++ (9)

Sé que find method encuentra la clave suministrada en std :: map y devuelve un iterador al elemento. ¿Hay alguna forma de encontrar el valor y obtener un iterador para el elemento? Lo que tengo que hacer es verificar que exista un valor especificado en std :: map. Lo hice haciendo un looping de todos los elementos en el mapa y comparando. Pero quería saber si hay un mejor enfoque para esto.

Esto es lo que he escrito

bool ContainsValue(Type_ value) { bool found = false; Map_::iterator it = internalMap.begin(); // internalMap is std::map while(it != internalMap.end()) { found = (it->second == value); if(found) break; ++it; } return found; }

Editar

¿Qué tal si usamos otro mapa internamente que almacena valor, combinación de teclas? Entonces, ¿puedo llamar para encontrarlo? ¿Está find () en std :: map haciendo una búsqueda secuencial?

Gracias


¿Qué tal si usamos otro mapa internamente que almacena valor, combinación de teclas? Entonces, ¿puedo llamar para encontrarlo?

Sí: mantenga dos mapas, con un mapa usando un tipo de clave y el otro usando el otro.

¿Está find () en std :: map haciendo una búsqueda secuencial?

No, es una búsqueda binaria de un árbol ordenado: su velocidad es O (log (n)).



No, debe recorrer el mapa std :: y verificar todos los valores manualmente. Dependiendo de lo que quiera hacer, puede ajustar std :: map en una clase simple que también almacena en caché todos los valores que se insertan en el mapa en algo que es fácilmente de búsqueda y no permite duplicados, como un std ::conjunto. No heredes de std :: map (¡no tiene un destructor virtual!), Pero envuélvelo para que puedas hacer algo como esto:

WrappedMap my_map< std::string, double >; my_map[ "key" ] = 99.0; std::set< double > values = my_map.values(); // should give back a set with only 99.0 in it

Una alternativa a rodar la suya sería usar el mapa bidireccional de Boost, que se encuentra fácilmente en las publicaciones a continuación o en Google.

Realmente depende de lo que desea hacer, la frecuencia con la que desea hacerlo y lo difícil que es rodar su propia clase de envoltorio frente a la instalación y el uso de Boost. Me encanta Boost, así que es una buena forma de hacerlo, pero hay algo bueno y completo acerca de cómo crear tu propia clase de envoltura. Tiene la ventaja de comprender directamente la complejidad de las operaciones, y es posible que no necesite el mapeo completo inverso de valores => que proporciona el mapa bidireccional de Boost.



Si tiene acceso a la excelente biblioteca de impulso , entonces debería usar boost :: multi_index para crear un mapa bidireccional, como dice Mark. A diferencia de un std :: map, esto le permite buscar ya sea por la clave o por el valor.

Si solo tiene el STL a mano, el siguiente código hará el truco (la plantilla para trabajar con cualquier tipo de mapa donde mapped_type soporte operator ==):

#include <map> #include <string> #include <algorithm> #include <iostream> #include <cassert> template<class T> struct map_data_compare : public std::binary_function<typename T::value_type, typename T::mapped_type, bool> { public: bool operator() (typename T::value_type &pair, typename T::mapped_type i) const { return pair.second == i; } }; int main() { typedef std::map<std::string, int> mapType; mapType map; map["a"] = 1; map["b"] = 2; map["c"] = 3; map["d"] = 4; map["e"] = 5; const int value = 3; std::map<std::string, int>::iterator it = std::find_if( map.begin(), map.end(), std::bind2nd(map_data_compare<mapType>(), value) ); if ( it != map.end() ) { assert( value == it->second); std::cout << "Found index:" << it->first << " for value:" << it->second << std::endl; } else { std::cout << "Did not find index for value:" << value << std::endl; } }


Posible que no entiendo completamente lo que estás tratando de lograr. Pero para probar simplemente si un mapa contiene o no un valor, creo que puede usar std::map ''s built in find .

bool ContainsValue(Type_ value) { return (internalMap.find(value) != internalMap.end()); }


prueba esta función:

template <class Map, class Val> typename Map::const_iterator MapSearchByValue(const Map & SearchMap, const Val & SearchVal) { Map::const_iterator iRet = SearchMap.end(); for (Map::const_iterator iTer = SearchMap.begin(); iTer != SearchMap.end(); iTer ++) { if (iTer->second == SearchVal) { iRet = iTer; break; } } return iRet; }

creo que es útil


Lo que está solicitando es precisamente lo que std :: find hace (no la función miembro)

template< class InputIt, class T > InputIt find( InputIt first, InputIt last, const T& value );


No es una opción muy buena, pero podría ser útil en algunos casos en los que el usuario está asignando un valor predeterminado como 0 o NULL en la inicialización.

Ex. < int , string > < string , int > < string , string > consider < string , string > mymap["1st"]="first"; mymap["second"]=""; for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it) { if ( it->second =="" ) continue; }