2011-02-11 11 views
6

tengo este mapa:¿Valor de mapa de acceso a través del índice?

m.insert(pair<int, string>(10, "map1")); 
m.insert(pair<int, string>(11, "map2")); 
m.insert(pair<int, string>(12, "map3")); 
m.insert(pair<int, string>(13, "map4")); 
m.insert(pair<int, string>(14, "map5")); 

Entonces, dejo que el usuario introduzca un número:

Please select: 
1. Map1 
2. Map2 
3. Map3 
4. Map4 
5. Map5 

Digamos que, si el usuario introduce 3, ¿cómo puedo obtener el valor: 12 ??

+0

¿Obtuvo el requisito correcto? Supongo que querías la clave al conocer el valor. – Jagannath

+0

Si el número entero en el par es su valor, entonces tiene su clave, par de valores en el orden opuesto. Debe ser 'pair '. Entonces, si el usuario selecciona '3', entonces puede buscarlo como:' m [cadena ("mapa") + cadena (itoa (selección))] '. – yasouser

+0

Me imaginé que la rutina para mostrar el menú se repetirá a través del contenedor, por lo que la opción del menú realmente sería (uno más que) el índice. La respuesta entonces es iterar el contenedor para identificar cuál fue la opción, tal como se hizo para mostrarla. – Steve314

Respuesta

3

std::map no rastrea el orden en que se insertan sus elementos; los elementos se almacenan en orden ordenado en lugar de orden de inserción. Si necesita realizar un seguimiento del orden en que se insertaron los elementos, debe hacerlo usted mismo. Una forma de hacer esto sería mantener un segundo recipiente que almacena las claves en orden, usando un std::vector, por ejemplo:

std::vector<int> insertion_order; 

m.insert(std::make_pair(10, "map1")); 
insertion_order.push_back(10); 

Entonces, la clave de los N ésimo elemento insertado está en el índice N - 1 en el insertion_order secuencia.

+0

No lo entiendo De esta manera: map > ?? ¿Es eso lo que quieres decir? –

+1

Mi sugerencia inicial fue menos que ideal (por decir lo menos). Considera esta nueva sugerencia. –

0

A partir de los documentos:

Compare: Clase de Comparación: Una clase que toma dos argumentos del tipo de clave y devuelve un bool. La expresión comp(a,b), donde comp es un objeto de esta clase de comparación y a y b son valores clave, devolverá verdadero si a debe colocarse en una posición anterior a b en una operación de ordenamiento estrictamente débil. Esto puede ser una clase que implementa un operador de llamada de función o un puntero a una función (ver constructor para un ejemplo). Por defecto es less<Key>, que devuelve lo mismo que aplicando el operador menor que (a<b). El objeto de mapa usa esta expresión para determinar la posición de los elementos en el contenedor. Todos los elementos en un contenedor de mapa se ordenan siguiendo esta regla en todo momento.

Así que la clase de mapa no mantiene el orden de sus elementos como lo haría una matriz. Si hubiera un operador de indexación, desearía no devolver el elemento i-ésimo agregado al mapa. Es una colección asociativa, y normalmente no utiliza ese tipo de estructura de datos cuando necesita mantener el orden en virtud del tiempo de inserción.

4

Con la configuración actual que tiene, no hay una manera fácil de hacerlo; Tendría que iterar sobre todos los elementos del mapa buscando el que tenía Map3 como valor.

El map está optimizado para buscar relaciones en una dirección. Dado un map<K, V>, puede mapear fácilmente desde K s al V s, pero no al revés. La razón es que debido a que puede almacenar cualquier V como valor, no hay garantía de que obtendrá un inverso único. Es decir, dado este mapa:

0 -> 0 
1 -> 0 
2 -> 1 

No hay una forma significativa de decir qué tecla tiene valor 0; hay dos de estas claves, 0 y 1.

Tiene muchas opciones aquí. En primer lugar, podría convertir el map en lugar de asociar cadenas con enteros, en lugar de números enteros con cadenas. De acuerdo con su caso de uso, esto parece ser lo que quería hacer en primer lugar.Si hiciera eso, entonces sólo podría utilizar el operador de corchetes para buscar el valor asociado:

cout << m["Map3"] << endl; 

O, si estaban preocupados por lo que pasaría con los valores que faltan, entonces se podría escribir

map<string, int>::iterator itr = m.find("Map3"); 
if (itr != m.end()) { 
    /* ... use itr to read the values ... */ 
} 

Alternativamente, si realmente tiene que tener el mapa de enteros a cadenas, y sabe que cada entero está emparejado con una cadena única y viceversa (es decir, el mapa es una biyección), entonces podría usar un Boost.Bimap para codificar esta relación bidireccional. Esto haría que sea muy fácil ir y venir entre las claves y los valores.

Espero que esto ayude!

2

Localiza los enteros en el menú con los datos que deseas almacenar. Considere:

struct data { 
    data(int n, const std::string& s) : s(s), n(n) { } 
    std::string s; 
    int n; 
}; 

// ... 
std::map<int,data> m; 
m.insert(make_pair(1, data(10, "Map1")); 
m.insert(make_pair(2, data(11, "Map2")); 
m.insert(make_pair(3, data(12, "Map3")); 

int n = m[3].n; // 12 
Cuestiones relacionadas