Простые приложения на С++
April 22, 2023

Удаление элементов из вектора в C++

Стереть элемент из вектора по значению 

Чтобы стереть элементы вектора по значению до С++ 20 необходимо:

#include <iostream>
#include <vector>

using namespace std;

int main() 
{
    vector<int> data{ 99, 0, 578, 0, 258, 0, 84759};
    cout << "\n\n\t\t";
    for (const auto& num : data) 
    {
        cout << num << '\t';
    }
    cout << "\n\n\t\t";
    const auto deleteObject = remove(data.begin(), data.end(), 0);
    data.erase(deleteObject, data.end());

    for (const auto& num : data) 
    {
        cout << num << '\t';
    }

    cout <<"\n\n\t\t";
    system("pause");
}

В C++20 есть функция std::erase(), которая позволяет стереть элемент вектора по значению.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    system("chcp 1251>nul");
    vector<int> data{ 5, 0, 10, 0, 12, 5, 74, 5 };
    cout << "\n\n\t\t";
    for (const auto& num : data)
    {
        cout << num << '\t';
    }

    cout << "\n\n\t\t";
    const auto number_of_deletions = erase(data, 5);
    cout  << " Количество удалённых элементов = "<< number_of_deletions<<"\n\n\t\t";

    for (const auto& num : data)
    {
        cout << num << '\t';
    }
    cout << "\n\n\t\t";
    system("pause");
}

Стереть элемент вектора по индексу

Стандартным решением для удаления элемента вектора является использование std::vector::erase(). Чтобы удалить элемент из вектора по его индексу, мы можем использовать арифметику указателя, как показано ниже:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

template <typename T>
void remove(vector<T>& v, size_t index) {
    v.erase(v.begin() + index);
}

int main()
{
    vector<int> data = { 15, 28, 54, 32, 99 };
    int index = 2; // 54

    cout << "\n\n\t\t";

    for (const auto& num : data)
    {
        cout << num<<" ";
    }

    remove(data, index);

    cout << "\n\n\t\t";

    copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));

    cout << "\n\n";
    system("pause");
    return 0;
}

В качестве альтернативы мы можем использовать std::advance() стандартный алгоритм для продвижения итератора на заданные позиции, чтобы указать на нужный индекс.

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

template <typename T>
void remove(vector<T>& v, size_t index)
{
    auto it = v.begin();
    advance(it, index);
    v.erase(it);
}

int main()
{
    vector<int> data = { 17, 2054, 34, 499, 51, 89, 387 };
    int index = 4; //51

    cout << "\n\n\t\t";

    for (const auto& num : data)
    {
        cout << num << " ";
    }

    remove(data, index);

    cout << "\n\n\t\t";

    copy(data.begin(), data.end(), ostream_iterator<int>(std::cout, " "));
    cout << "\n\n";
    system("pause");
    return 0;
}

Условное удаление элементов вектора

Стандартное решение для условного удаления элементов вектора:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
    vector<int> data= { 11, 32, 43, 44, 15, 77, 20 };

    cout << "\n\n\t\t";
    for (const auto& num : data)
    {
        cout << num <<" ";
    }
    data.erase(remove_if(data.begin(), data.end(), [](const int& x) {return x % 2 == 0;}), data.end());

    cout << "\n\n\t\t";
    copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
    cout << "\n\n\t\t";
    system("pause");
    return 0;
}

Начиная с C++20, мы можем использовать std::erase_if() алгоритм, который стирает все элементы из вектора, удовлетворяющего предоставленному предикату. Он определен в заголовке <vector>

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
    vector<string> data{ "vova","vita","vasq","vova","luna","vita" };

    cout << "\n\n\t\t";

    for (const auto& num : data)
    {
        cout << num <<" ";
    }

    cout << "\n\n\t\t";
    erase_if(data, [](auto str) { return str == "vova"; });

    copy(data.begin(), data.end(), ostream_iterator<string>(cout, " "));

    cout << "\n\n\t\t";
    system("pause");
}

Универсальный метод для условного стирания элементов вектора.

#include <iostream>
#include <vector>
#include<random>

using namespace std;

class num
{
    int m_number = 0;
public:

    void setnum(int num)
    {
        m_number = num;
    }

    int getnum() const
    {
       return m_number;
    }
};


void if_less_erase(vector<num>& mydata, int less)
{
    vector<num> tmpdata;

    for (int i = 0; i < mydata.size(); i++)
    {
        if (mydata[i].getnum() > less) tmpdata.emplace_back(mydata[i]);
    }
    mydata.clear();

    for (int i = 0; i < tmpdata.size(); i++)
    {
        mydata.emplace_back(tmpdata[i]);
    }
}


int main()
{

    random_device rd;

    mt19937 gen(rd());

    uniform_int_distribution<> rside(100, 1000);

    vector<num> data;

    for (int i=0;i<10;i++)
    {
        data.emplace_back(num());
        data[i].setnum(rside(gen));
    }

    cout << "\n\n\t\t";

    for (const auto& num : data)
    {
        cout << num.getnum() <<" ";
    }

    if_less_erase(data, 500);

    cout << "\n\n\t\t";

    for (const auto& num : data)
    {
        cout << num.getnum() << " ";
    }

    cout << "\n\n\t\t";
    system("pause");
}

Скачать код