Como verificar se std :: map contém uma chave sem fazer inserção?


Respostas:


305

Use my_map.count( key ); ele pode retornar apenas 0 ou 1, que é essencialmente o resultado booleano que você deseja.

Como alternativa my_map.find( key ) != my_map.end()também funciona.


40
@ John: Isso cheira a otimização prematura. No GCC (e tenho certeza de sistemas mais razoáveis), map::counté implementado como find(__x) == end() ? 0 : 1;. Para multimapvocê, pode ter um argumento de desempenho, mas essa não é a pergunta da OP e ainda prefiro elegância.
Potatoswatter

42
Não, o argumento de otimização prematuro é válido apenas se a otimização exigir algum esforço, o que, nesse caso, não é necessário.
markh44

13
Não é verdade. Não é prematuro se facilita a leitura do código ou elimina despesas desnecessárias. Nesse caso, se count () for implementado via find () de qualquer maneira, chamar find () eliminará diretamente uma chamada de função ... ergo, é uma otimização madura . Acho que usar a chamada find () também é mais óbvio, mas isso é uma preferência puramente pessoal.
Tim Keating

9
Não é uma otimização prematura estar ciente do desempenho das funções da biblioteca antes de criar o hábito de usá-las. Nesse caso, você está certo, não importa, mas também não faz a minúscula diferença estilística entre encontrar e contar. Acho que você leva a retórica da 'otimização prematura' longe demais. Você deve adotar quaisquer hábitos de otimização "gratuitos" que puder encontrar e usá-los para o desenvolvimento diário. É quando os codificadores sucumbem à armadilha de pagar custos em legibilidade / dev time / etc, tudo por "ganhos de desempenho" não medidos que a retórica prematura da otimização se torna o conselho certo a dar.
VoidStar 24/02

10
Longe, o std deve apenas adicionar uma maldita has(k)/ contains(k)como todas as outras classes de mapas sãos do planeta. Design de interface ruim. A abordagem find () é muito detalhada e count(k)definitivamente não está em paridade semântica com has(k). Para esse assunto também não é find(k). Confira a contagem de visualizações desta pergunta.
Jarrod Smith

46

A resposta de Potatoswatter está bem, mas prefiro usar findou lower_boundnão. lower_boundé especialmente útil porque o iterador retornado pode ser usado posteriormente para uma inserção sugerida, caso você deseje inserir algo com a mesma chave.

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}

Isso é sutilmente diferente de como ele diz que está fazendo isso ... a única diferença é que o cálculo de valuepode ser ignorado se a inserção for desnecessária.
Potatoswatter 07/10/10

1
Claro, eu entendo que o OP não quer inserir, portanto, uma lower_boundsolução baseada em excesso é um exagero. Eu meio que acabei de mencionar minha resposta "por completude"; como eu disse, o seu é perfeitamente adequado. :-)
Chris Jester-Young

4
Sim, esta é uma boa resposta e não discordo de nada. Apenas apontando a relação com a alternativa inserta priori. Na verdade, há outra diferença se, usando a multimap, o lower_boundmétodo é inserido no início do intervalo equivalente, enquanto o insertmétodo simples é adicionado ao final do intervalo.
Potatoswatter 07/10/10

2
Não é a resposta para a pergunta, mas minha pergunta ruim me leva à resposta correta aqui ... Preciso fazer a inserção / atualização. : D
Hunter-Orionnoir

1
@ Hunter Você pode me mostrar seu código? Se não for grande, provavelmente posso analisá-lo para você.
Chris Jester-Young

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.