2010-12-06 12 views
7

posibles duplicados:
Checking value exist in a std::map - C++
How to traverse a stl map/vector/list/etc?Buscar valor específico en std :: mapa

Hola,

¿Es posible buscar un valor específico en std: : mapa, sin saber la clave? Sé que podría iterar sobre un mapa completo y comparar valores, pero ¿es posible hacerlo utilizando una función de algoritmos estándar?

+1

Para 'std :: map', tendrá que repetir. De lo contrario, use 'boost :: bimap' - http://stackoverflow.com/questions/535317/checking-value-exist-in-a-stdmap-c – birryree

+0

Este enlace muestra cómo atravesar un mapa ^^^ –

Respuesta

4

¿Esto es útil? STL find_if

Necesita tener algún tipo de predicado, ya sea un puntero de función o un objeto con operator() implementado. Dicho predicado debería tomar solo un parámetro.

8

Puede usar Boost.Bimap si desea indexar valores y claves. Sin esto o similar, esto tendrá que hacerse por fuerza bruta (=> escanear a mano el map).

Boost.Bimap es una biblioteca de mapas bidireccionales para C++. Con Boost.Bimap usted puede crear contenedores asociativos en que ambos tipos pueden usarse como clave.

+0

+ 1. Además, puede usar dos mapas STL opuestos, si no está permitido usar Boost en su código. – Stas

+1

@Stas - cierto, pero esto hace más trabajo - mi respuesta habitual a las personas que no tienen permitido usar Boost es descargar los encabezados de todos modos y extraer el código que necesita. –

2

Existen formas (incómodas) de hacer esto usando funciones estándar (por ejemplo, std::find_if), pero estas todavía implican iterar sobre todo el mapa. Boost.Bimap proporcionará indexación eficiente en ambas direcciones, y puede ir aún más lejos con Boost.Multi-Index.

12

Bueno, se podría utilizar std::find_if:

int main() 
{ 
    typedef std::map<int, std::string> my_map; 

    my_map m; 
    m.insert(std::make_pair(0, "zero")); 
    m.insert(std::make_pair(1, "one")); 
    m.insert(std::make_pair(2, "two")); 

    const std::string s("one"); 
    const my_map::const_iterator it = std::find_if(
     m.begin(), m.end(), boost::bind(&my_map::value_type::second, _1) == s 
    ); 
} 

Pero eso es sólo un poco mejor que un lazo hecho a mano: es todavía O(n).

+0

¡Gran idea con bind! –

+0

Necesité algo de tiempo para entender el uso de boost :: bind. Aquí hay algunos consejos si alguien los necesita: [Variables de miembros vinculantes] (http://www.boost.org/doc/libs/1_65_1/libs/phoenix/doc/html/phoenix/modules/bind/binding_member_variables.html) y [Operadores sobrecargados] (http://www.boost.org/doc/libs/1_65_1/libs/bind/doc/html/bind.html#bind.purpose.overloaded_operators_new_in_boos) – guini

Cuestiones relacionadas