Saya melihat dokumentasi API untuk vektor stl, dan memperhatikan tidak ada metode pada kelas vektor yang memungkinkan penghapusan elemen dengan nilai tertentu. Ini tampak seperti operasi yang umum, dan tampaknya aneh bahwa tidak ada cara untuk melakukannya.
145
Jawaban:
std::remove
tidak benar-benar menghapus elemen dari wadah, tetapi mengembalikan iterator akhir baru yang dapat diteruskan kecontainer_type::erase
untuk melakukan penghapusan NYATA dari elemen tambahan yang sekarang di akhir wadah:sumber
vec.end()
dijamin sama di kedua sisi panggilanstd::remove
? Sepertinya saya membaca bagian lain dari web seperti ini aman, tetapi harus dinyatakan dengan jelas.vec.end()
tidak harus sama; itu hanya perlu benar (yang itu).vec.end()
memang harus sama, tapi tidak apa-apa karenastd::remove
tidak mengubahnya. Jika memang mengubahnya (dan membatalkan nilai lama) maka akan ada masalah: urutan evaluasi parameter tidak ditentukan dan karena itu Anda tidak akan tahu apakah yang keduavec.end()
masih valid pada saat itu digunakan. Alasannya sama sederhana,std::remove
tidak mengubah ukuran wadah, hanya memindahkan isi.std::remove
hanya membawa satu argumen; yangconst char *_Filename
. Metode apa yang harus saya panggil?remove
yang menghapus file. Anda harus memasukkan<algorithm>
untuk mengakses versiremove
yang berhubungan dengan kontainer.Jika Anda ingin menghapus sebuah item, berikut ini akan menjadi sedikit lebih efisien.
atau Anda dapat menghindari overhead memindahkan barang jika pesanan tidak penting bagi Anda:
sumber
Gunakan metode global std :: remove dengan iterator begin dan end, dan kemudian gunakan std :: vector.erase untuk benar-benar menghapus elemen.
Tautan dokumentasi
std :: hapus http://www.cppreference.com/cppalgorithm/remove.html
std :: vector.erase http://www.cppreference.com/cppvector/erase.html
Terima kasih kepada Jim Buck karena menunjukkan kesalahan saya.
sumber
Jawaban lain mencakup cara melakukan ini dengan baik, tapi saya pikir saya juga akan menunjukkan bahwa ini tidak benar-benar aneh bahwa ini tidak ada dalam vektor API: itu tidak efisien, pencarian linear melalui vektor untuk nilai, diikuti oleh banyak menyalin untuk menghapusnya.
Jika Anda melakukan operasi ini secara intensif, sebaiknya pertimbangkan std :: set sebagai ganti karena alasan ini.
sumber
Jika Anda memiliki vektor yang tidak disortir, maka Anda cukup bertukar dengan elemen vektor terakhir
resize()
.Dengan wadah memerintahkan, Anda akan pergi terbaik dengan
std::vector::erase()
. Perhatikan bahwa ada yangstd::remove()
didefinisikan dalam<algorithm>
, tetapi itu tidak benar-benar melakukan penghapusan. (Baca dokumentasi dengan cermat).sumber
Solusi yang lebih pendek (yang tidak memaksa Anda mengulangi nama vektor 4 kali) adalah menggunakan Boost:
Lihat http://www.boost.org/doc/libs/1_64_0/libs/range/doc/html/range/reference/algorithms/new/remove_erase.html
sumber
Dari c ++ 20 :
Fungsi non-anggota diperkenalkan
std::erase
, yang mengambil vektor dan nilai untuk dihapus sebagai input.ex:
sumber
map::erase
!Lihat juga std :: remove_if untuk dapat menggunakan predikat ...
Inilah contoh dari tautan di atas:
sumber
Jika Anda ingin melakukannya tanpa tambahan termasuk:
sumber
Ada dua cara yang dapat Anda gunakan untuk menghapus item khususnya. mari kita ambil vektor
1) Cara tidak efisien: Meskipun tampaknya cukup efisien tetapi itu bukan karena fungsi hapus menghapus elemen dan menggeser semua elemen ke kiri oleh 1. sehingga kompleksitasnya adalah O (n ^ 2)
2) Cara efisien (DISARANKAN) : Ini juga dikenal sebagai idiom - HAPUS .
output dari algoritma hapus adalah:
sebagai jenis pengembalian hapus adalah iterator ke ujung baru dari rentang itu.
Sekarang gunakan fungsi hapus vektor untuk menghapus elemen dari ujung baru ke ujung lama vektor. Membutuhkan O (1) waktu.
jadi metode ini bekerja di O (n)
sumber
*
*
C ++ 20 menyediakan cara mudah untuk melakukannya sekarang. Menjadi sesederhana:
Anda harus memeriksa std :: erase dan std :: erase_if .
Tidak hanya akan menghapus semua elemen dari nilai (di sini '0'), itu akan melakukannya dalam kompleksitas waktu O (n) . Mana yang terbaik yang bisa Anda dapatkan.
Jika kompiler Anda tidak mendukung C ++ 20, Anda harus menggunakan idiom hapus-hapus :
sumber