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

    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());
    Ответ написан
    Комментировать