Lo que quiero decir es que sabemos que los std::map
elementos están ordenados según las claves. Entonces, digamos que las claves son enteros. Si iterate de std::map::begin()
que std::map::end()
el uso de un for
, hace la garantía estándar que voy a iterar por consiguiente, a través de los elementos con claves, en orden ascendente?
Ejemplo:
std::map<int, int> map_;
map_[1] = 2;
map_[2] = 3;
map_[3] = 4;
for( std::map<int, int>::iterator iter = map_.begin();
iter != map_.end();
++iter )
{
std::cout << iter->second;
}
¿Se garantiza que se imprima 234
o se define su implementación?
Razón de la vida real: tengo una std::map
con int
llaves. En situaciones muy raras, me gustaría recorrer todos los elementos, con clave, mayor que un int
valor concreto . Sí, parece std::vector
que sería la mejor opción, pero observe mis "situaciones muy raras".
EDITAR : Sé que los elementos de std::map
están ordenados ... no es necesario señalarlo (para la mayoría de las respuestas aquí). Incluso lo escribí en mi pregunta.
Estaba preguntando sobre los iteradores y el orden cuando estoy iterando a través de un contenedor. Gracias @Kerrek SB por la respuesta.
fuente
map::upper_bound
para encontrar el punto para comenzar a iterar.Respuestas:
Si, eso está garantizado. Por otra parte,
*begin()
le da el más pequeño y*rbegin()
el elemento más grande, según lo determinado por el operador de comparación, y dos valores clavea
yb
para los que la expresión!compare(a,b) && !compare(b,a)
es verdadera se consideran iguales. La función de comparación predeterminada esstd::less<K>
.El orden no es una característica de bonificación afortunada, sino que es un aspecto fundamental de la estructura de datos, ya que el orden se utiliza para determinar cuándo dos claves son iguales (según la regla anterior) y para realizar una búsqueda eficiente (esencialmente un binario búsqueda, que tiene complejidad logarítmica en el número de elementos).
fuente
std::unordered_map
tiene un tiempo de búsqueda más eficiente de O (1). La ventaja destd::map
está en el orden de las claves, pero no en la búsqueda.Esto está garantizado por los requisitos de contenedor asociativo en el estándar C ++. Por ejemplo, ver 23.2.4 / 10 en C ++ 11:
y 23.2.4 / 11
fuente
Creo que hay una confusión en las estructuras de datos.
En la mayoría de los idiomas, a
map
es simplemente un Contenedor Asociativo: asigna una clave a un valor. En los idiomas "más nuevos", esto generalmente se logra utilizando un mapa hash, por lo que no se garantiza ningún orden.En C ++, sin embargo, esto no es así:
std::map
es un contenedor asociativo ordenadostd::unordered_map
es un contenedor asociativo basado en tablas hash introducido en C ++ 11Entonces, para aclarar las garantías en el pedido.
En C ++ 03:
std::set
,std::multiset
,std::map
Ystd::multimap
están garantizados para ser ordenados de acuerdo a las teclas (y el criterio suministrado)std::multiset
ystd::multimap
, el estándar no impone ninguna garantía de orden en elementos equivalentes (es decir, aquellos que se comparan igual)En C ++ 11:
std::set
,std::multiset
,std::map
Ystd::multimap
están garantizados para ser ordenados de acuerdo a las teclas (y el criterio suministrado)std::multiset
ystd::multimap
, el Estándar impone que los elementos equivalentes (aquellos que comparan iguales) se ordenan de acuerdo con su orden de inserción (primero se inserta primero)std::unordered_*
Los contenedores, como su nombre lo indica, no están ordenados. En particular, el orden de los elementos puede cambiar cuando se modifica el contenedor (tras la inserción / eliminación).Cuando el Estándar dice que los elementos están ordenados de alguna manera, significa que:
Espero que esto aclare cualquier confusión.
fuente
Sí,
std::map
es un contenedor ordenado, ordenado por elKey
con el suministradoComparator
. Entonces está garantizado.Eso seguramente es posible.
fuente
Sí ... los elementos en un
std::map
tienen un orden débil estricto, lo que significa que los elementos estarán compuestos de un conjunto (es decir, no habrá repeticiones de claves que sean "iguales"), y la igualdad se determina mediante la prueba en cualquier dos teclas A y B, que si la tecla A no es menor que la tecla B y B no es menor que A, entonces la tecla A es igual a la tecla B.Dicho esto, no puede ordenar adecuadamente los elementos de a
std::map
si el orden débil para ese tipo es ambiguo (en su caso, donde está utilizando enteros como tipo de clave, eso no es un problema). Debe poder definir una operación que defina un orden total en el tipo que está utilizando para las claves en sustd::map
, de lo contrario, solo tendrá un orden parcial para sus elementos, o poset, que tiene una propiedad donde A puede no ser comparable a B. Lo que sucederá normalmente en este escenario es que podrá insertar los pares clave / valor, pero puede terminar con pares clave / valor duplicados si recorre todo el mapa y / o detecta "falta" pares clave / valor cuando intenta realizar unstd::map::find()
par de clave / valor específico en el mapa.fuente
begin () puede dar el elemento más pequeño. Pero su implementación dependía. ¿Se especifica en el estándar C ++? Si no, entonces es peligroso hacer esta suposición.
fuente