@xz-xz-2011

Как сравнить 2 вектора и удалить элементы из второго?

Есть такая структура и инициализация.
Вопрос, нужно удалить те элементы в myVec векторе, чьих id нет в newVec. Как лучше это сделать.
Заранее спасибо.
public:
    A();
    int id;
    std::string value;


A a;
    a.id = 1;
    a.value = "mm";
 
    A b;
    b.id = 2;
    b.value = "aa";
 
    A c;
    c.id = 3;
    c.value = "cc";
 
    A d;
    d.id = 4;
    d.value = "cc";
 
    vector<A> newVec;
    newVec.push_back(a);
    newVec.push_back(b);
    newVec.push_back(d);
 
    vector<A> myVec;
    myVec.push_back(a);
    myVec.push_back(c);
  • Вопрос задан
  • 1382 просмотра
Решения вопроса 1
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
Первый вариант -- просто сделать это:
std::erase(
	std::remove_if(myVec.begin(), myVec.end(), 
		[&newVec](const A &a)
		{
			return std::find_if(newVec.begin(), newVec.end(), [&a](const A &newA){ return a.id ==  newA.id; }) == newVec.end();
		}),
	myVec.end());


Для упрощения можно перегрузить оператор == для A так, чтобы он сравнивал id:
struct A
{
	//...
	bool operator==(const A &other) const
	{
		return a.id == other.id;
	}
	//...
};

std::erase(
	std::remove_if(myVec.begin(), myVec.end(), 
		[&newVec](const A &a)
		{
			return std::find(newVec.begin(), newVec.end(), a) == newVec.end();
		}),
	myVec.end());


Эти решения будут пробегать по всем элементам из newVec для каждого элемента в myVec. Уже при размере в 1000 элементов для каждого, надо будет сделать 1 000 000 сравнений. ВЫход -- использовать set или unordered_set:

namespace std
{
	//для unordered_set
	template<>
	struct hash<A>
	{
		std::size_t operator()(const A &a)
		{
			return std::hash<int>()(a.id);
		}
	}

	//для std::set
	template<>
	struct less<A>
	{
		bool operator()(const A &lha, const A &rha)
		{
			return lha.id < rha.id;
		}
	}
}

std::unordered_set<A> newSet;
//std::set<A> newSet

newSet.insert(a);
newSet.insert(b);
newSet.insert(d);

std::erase(
	std::remove_if(myVec.begin(), myVec.end(), 
		[&newSet](const A &a)
		{
			return newSet.find(a) == newSet.end();
		}),
	myVec.end());
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы