O que quero dizer é - sabemos que os std::map
elementos do são classificados de acordo com as chaves. Então, digamos que as chaves sejam números inteiros. Se eu iterar de std::map::begin()
para std::map::end()
usar a for
, o padrão garante que eu iterarei consequentemente através dos elementos com chaves, classificados em ordem crescente?
Exemplo:
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;
}
Isso é garantido para impressão 234
ou sua implementação está definida?
Razão da vida real: eu tenho um std::map
com int
chaves. Em situações muito raras, eu gostaria de percorrer todos os elementos, com chave, maior que um int
valor concreto . Sim, parece que std::vector
seria a melhor escolha, mas observe minhas "situações muito raras".
EDIT : Eu sei, que os elementos de std::map
são classificados .. não há necessidade de apontar (para a maioria das respostas aqui). Eu até escrevi na minha pergunta.
Eu estava perguntando sobre os iteradores e o pedido quando estou iterando através de um contêiner. Obrigado @Kerrek SB pela resposta.
fonte
map::upper_bound
para encontrar o ponto para começar a iterar.Respostas:
Sim, isso é garantido. Além disso,
*begin()
fornece o menor e*rbegin()
o maior elemento, conforme determinado pelo operador de comparação, e dois valores principaisa
eb
para os quais a expressão!compare(a,b) && !compare(b,a)
é verdadeira são considerados iguais. A função de comparação padrão éstd::less<K>
.A ordenação não é um recurso de bônus da sorte, mas sim, é um aspecto fundamental da estrutura de dados, pois a ordenação é usada para determinar quando duas chaves são iguais (pela regra acima) e para executar uma pesquisa eficiente (essencialmente uma variável binária). pesquisa, que possui complexidade logarítmica no número de elementos).
fonte
std::unordered_map
tem um tempo de pesquisa mais eficiente de O (1). A vantagem destd::map
está na ordenação de chaves, mas não na pesquisa.Isso é garantido pelos requisitos de contêiner associativo no padrão C ++. Por exemplo, veja 23.2.4 / 10 em C ++ 11:
e 23.2.4 / 11
fonte
Eu acho que há uma confusão nas estruturas de dados.
Na maioria dos idiomas, a
map
é simplesmente um AssociativeContainer: ele mapeia uma chave para um valor. Nos idiomas "mais recentes", isso geralmente é alcançado usando um mapa de hash, portanto, nenhuma ordem é garantida.Em C ++, no entanto, isso não é assim:
std::map
é um contêiner associativo classificadostd::unordered_map
é um contêiner associativo baseado em tabela de hash introduzido no C ++ 11Portanto, para esclarecer as garantias sobre o pedido.
No C ++ 03:
std::set
,std::multiset
,std::map
Estd::multimap
são garantidos para ser ordenados de acordo com as teclas (e o critério fornecido)std::multiset
estd::multimap
, a norma não impõe nenhuma garantia de ordem a elementos equivalentes (ou seja, aqueles que se comparam da mesma forma)No C ++ 11:
std::set
,std::multiset
,std::map
Estd::multimap
são garantidos para ser ordenados de acordo com as teclas (e o critério fornecido)std::multiset
estd::multimap
, a Norma impõe que elementos equivalentes (aqueles que se comparam iguais) sejam ordenados de acordo com sua ordem de inserção (primeiro inseridos primeiro)std::unordered_*
recipientes não são, como o nome indica, ordenado. Mais notavelmente, a ordem dos elementos pode mudar quando o contêiner é modificado (mediante inserção / exclusão).Quando a Norma diz que os elementos são ordenados de certa forma, significa que:
Espero que isso esclareça qualquer confusão.
fonte
Sim,
std::map
é um contêiner classificado, encomendado peloKey
com o fornecidoComparator
. Portanto, é garantido.Isso é certamente possível.
fonte
Sim ... os elementos em um
std::map
têm uma ordem estrita estrita, o que significa que os elementos serão compostos por um conjunto (ou seja, não haverá repetições de chaves "iguais"), e a igualdade é determinada pelo teste em qualquer duas chaves A e B, que se a chave A não for menor que a chave B e B não for menor que A, a chave A será igual à chave B.Dito isto, você não pode classificar adequadamente os elementos de a
std::map
se a ordem fraca desse tipo for ambígua (no seu caso, onde você está usando números inteiros como o tipo de chave, isso não é um problema). Você deve ser capaz de definir uma operação que defina uma ordem total do tipo que você está usando para as chaves no seustd::map
, caso contrário, você terá apenas um pedido parcial para seus elementos, ou poset, que possui propriedade onde A pode não ser comparável a B. O que normalmente acontecerá nesse cenário é que você poderá inserir os pares de chave / valor, mas poderá acabar com pares de chave / valor duplicados se percorrer o mapa inteiro e / ou detectar "falta" pares de chave / valor quando você tenta executar umstd::map::find()
par específico de chave / valor no mapa.fonte
begin () pode fornecer o menor elemento. Mas isso depende da implementação. É especificado no padrão C ++? Caso contrário, é perigoso fazer essa suposição.
fonte