Eu estava olhando a documentação da API para o vetor stl e notei que não havia um método na classe vetorial que permitisse a remoção de um elemento com um determinado valor. Isso parece uma operação comum e parece estranho que não haja uma maneira integrada de fazer isso.
145
Respostas:
std::remove
na verdade, não apaga o elemento do contêiner, mas retorna o novo iterador final que pode ser passado paracontainer_type::erase
a remoção REAL dos elementos extras que estão agora no final do contêiner:fonte
vec.end()
garantido que seja o mesmo nos dois lados da chamadastd::remove
? Parece-me que a leitura de outras partes da Web é segura, mas deve ser declarada claramente.vec.end()
não precisa ser o mesmo; só precisa estar correto (qual é).vec.end()
precisa ser o mesmo, mas tudo bem, porquestd::remove
não muda. Se o alterasse (e invalidasse o valor antigo), haveria um problema: a ordem de avaliação dos parâmetros não é especificada e, portanto, você não saberia se o segundovec.end()
ainda é válido no momento em que é usado. O motivo é o mesmo: é simples,std::remove
não altera o tamanho do contêiner, apenas move o conteúdo.std::remove
apenas um argumento; que éconst char *_Filename
. Qual método eu preciso chamar?remove
que exclui um arquivo. Você precisa incluir<algorithm>
para acessar a versãoremove
que lida com contêineres.Se você deseja remover um item, o seguinte será um pouco mais eficiente.
ou você pode evitar a sobrecarga de mover os itens se o pedido não for importante para você:
fonte
Use o método global std :: remove com o iterador de início e fim e, em seguida, use std :: vector.erase para remover os elementos.
Links da documentação
std :: remove http://www.cppreference.com/cppalgorithm/remove.html
std :: vector.erase http://www.cppreference.com/cppvector/erase.html
Agradecemos a Jim Buck por apontar meu erro.
fonte
As outras respostas abrangem como fazer isso bem, mas também gostaria de salientar que não é realmente estranho que isso não esteja na API do vetor: é uma pesquisa ineficiente e linear pelo valor do vetor, seguida por um monte de copiar para removê-lo.
Se você estiver fazendo essa operação intensivamente, pode valer a pena considerar std :: set por esse motivo.
fonte
Se você tiver um vetor não classificado, poderá simplesmente trocar com o último elemento vetorial
resize()
.Com um recipiente ordenou, você será melhor fora com
std::vector::erase()
. Observe que existe umstd::remove()
definido em<algorithm>
, mas que na verdade não faz a exclusão. (Leia a documentação cuidadosamente).fonte
Uma solução mais curta (que não o força a repetir o nome do vetor quatro vezes) seria usar o Boost:
Consulte http://www.boost.org/doc/libs/1_64_0/libs/range/doc/html/range/reference/algorithms/new/remove_erase.html
fonte
A partir do c ++ 20 :
Uma função não membro introduzida
std::erase
, que leva o vetor e o valor a serem removidos como entradas.ex:
fonte
map::erase
!Veja também std :: remove_if para poder usar um predicado ...
Aqui está o exemplo do link acima:
fonte
Se você quiser fazer isso sem nenhum extra, inclua:
fonte
Existem duas maneiras pelas quais você pode usar para apagar um item particularmente. vamos pegar um vetor
1) Maneira não eficiente: embora pareça ser bastante eficiente, mas não é porque a função apagar apaga os elementos e muda todos os elementos para a esquerda por 1., de modo que sua complexidade será O (n ^ 2)
2) Maneira eficiente (RECOMENDADO) : Também é conhecido como expressões ERASE - REMOVE .
A saída do algoritmo de remoção é:
como o tipo de retorno de remoção é o iterador para o novo final desse intervalo.
Agora use a função de exclusão do vetor para excluir elementos do novo extremo para o antigo do vetor. Requer tempo O (1).
então esse método funciona em O (n)
fonte
*
*
O C ++ 20 oferece uma maneira fácil de fazer isso agora. Fica tão simples quanto:
Você deve verificar std :: erase e std :: erase_if .
Não apenas removerá todos os elementos do valor (aqui '0'), mas também o fará com complexidade de tempo O (n) . Qual é o melhor que você pode obter.
Se o seu compilador não suportar C ++ 20, você deverá usar o idioma erase-remove :
fonte