Saya ingin menghapus elemen dari vektor menggunakan metode hapus. Tetapi masalahnya di sini adalah bahwa elemen tersebut tidak dijamin hanya terjadi sekali dalam vektor. Ini mungkin ada beberapa kali dan saya perlu menghapus semuanya. Kode saya adalah seperti ini:
void erase(std::vector<int>& myNumbers_in, int number_in)
{
std::vector<int>::iterator iter = myNumbers_in.begin();
std::vector<int>::iterator endIter = myNumbers_in.end();
for(; iter != endIter; ++iter)
{
if(*iter == number_in)
{
myNumbers_in.erase(iter);
}
}
}
int main(int argc, char* argv[])
{
std::vector<int> myNmbers;
for(int i = 0; i < 2; ++i)
{
myNmbers.push_back(i);
myNmbers.push_back(i);
}
erase(myNmbers, 1);
return 0;
}
Kode ini jelas macet karena saya mengubah ujung vektor sambil mengulanginya. Apa cara terbaik untuk mencapai ini? Yaitu adakah cara untuk melakukan ini tanpa melakukan iterasi melalui vektor beberapa kali atau membuat satu salinan vektor lagi?
std::remove()
menggeser elemen sedemikian rupa sehingga elemen yang akan dihapus ditimpa. Algoritme tidak mengubah ukuran penampung, dan jikan
elemen dihapus maka tidak ditentukan apan
elemen terakhir .Memanggil hapus akan membatalkan iterator, Anda dapat menggunakan:
Atau Anda bisa menggunakan std :: remove_if bersama dengan functor dan std :: vector :: erase:
Alih-alih menulis functor Anda sendiri dalam hal ini, Anda dapat menggunakan std :: remove :
Di C ++ 11 Anda bisa menggunakan lambda alih-alih functor:
Di C ++ 17 std :: eksperimental :: erase dan std :: eksperimental :: erase_if juga tersedia, di C ++ 20 ini (akhirnya) diganti namanya menjadi std :: erase dan std :: erase_if :
atau:
sumber
erase
denganremove
adalah cara kanonik untuk melakukan ini.Anda dapat melakukan iterasi menggunakan akses indeks,
Untuk menghindari kompleksitas O (n ^ 2) Anda dapat menggunakan dua indeks, i - indeks pengujian saat ini, j - indeks untuk menyimpan item berikutnya dan pada akhir siklus ukuran baru dari vektor.
kode:
Dalam kasus seperti itu, Anda tidak memiliki iterator yang tidak valid, kompleksitasnya adalah O (n), dan kode sangat ringkas dan Anda tidak perlu menulis beberapa kelas helper, meskipun dalam beberapa kasus menggunakan kelas helper bisa mendapatkan keuntungan dalam kode yang lebih fleksibel.
Kode ini tidak menggunakan
erase
metode, tetapi menyelesaikan tugas Anda.Menggunakan stl murni Anda dapat melakukan ini dengan cara berikut (ini mirip dengan jawaban Motti):
sumber
Bergantung pada mengapa Anda melakukan ini, menggunakan std :: set mungkin merupakan ide yang lebih baik daripada std :: vector.
Ini memungkinkan setiap elemen terjadi hanya sekali. Jika Anda menambahkannya beberapa kali, hanya akan ada satu contoh untuk dihapus. Ini akan membuat operasi penghapusan menjadi sepele. Operasi penghapusan juga akan memiliki kompleksitas waktu yang lebih rendah daripada pada vektor, namun, menambahkan elemen lebih lambat di set sehingga mungkin tidak banyak menguntungkan.
Ini tentu saja tidak akan berfungsi jika Anda tertarik pada berapa kali elemen telah ditambahkan ke vektor Anda atau urutan elemen ditambahkan.
sumber
Untuk menghapus elemen pertama, Anda dapat menggunakan:
sumber