Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have two vectors. I need to remove second vector elements that does not matched with first vector element.

Example:
C++
vector < string > v1 ={"str1"};
vector < string > v2 ={"str2", "str1", "str3"};

So, I need to remove v2 elements that is not common to v1 elemnts.

I want to make v2 now as v2 = {"str1"};

What I have tried:

C++
#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
  vector < string > v1 ={"str1"};
  vector < string > v2 ={"str2", "str1", "str3"};

  for (auto it = v1.begin (); it != v1.end (); it++)
    {
        auto fit = std::find (v2.begin (), v2.end (), *it);
        if (fit != v2.end ())
	    {
	        std::cout << "Element " << *fit << " found at position : ";
	        std::cout << fit - v2.begin() << " (counting from zero) \n" ;
	    }
	    else
	    {
          std::cout << "Element not found.\n\n";
          //remove v2 elements not matched with v1 elements
	    }
      }
   return 0; 
}
Posted
Updated 11-Jan-22 22:51pm
v2
Comments
Richard MacCutchan 12-Jan-22 3:53am    
You just need to check each element of v2 to see if it exists in v1. If it does not then remove it from v2.
Member 14036158 12-Jan-22 4:07am    
i am doing in else part
if (fit != v2.end ())
{
std::cout << "Element " << *fit << " found at position : ";
std::cout << fit - v2.begin() << " (counting from zero) \n" ;
}
else
{
v2.erase(fit);
}
But, its not working.
Richard MacCutchan 12-Jan-22 4:24am    
Your outer loop is looking for elements of v1 that exist in v2. And since v1 only contains a single element, the loop ends after one iteration. You need to iterate over the elements of v2, looking for matches in v1, as I suggested above.
Richard MacCutchan 12-Jan-22 4:38am    
See my (partial) solution below.
Forget that, the solution provided by CPallini is the perfect answer.
Rick York 12-Jan-22 12:04pm    
In general, a vector is not a good container to use if deletions of this nature are required. A list is better if this is necessary.

Your logic is correct, however instead of v1 searching in v2, we should search v2 in v1 and remove items not present in v1.

for (auto it = v2.begin (); it != v2.end (); it++)
  {
      auto fit = std::find (v1.begin (), v1.end (), *it);
      if (fit != v1.end ())
      {
          std::cout << "Element " << *fit << " found at position : ";
          std::cout << fit - v2.begin() << " (counting from zero) \n" ;
      }
      else
      {
        std::cout << "Element not found.\n\n";
        remove(v2.begin(), v2.end(), *fit);
      }
    }
 return
 
Share this answer
 
Comments
CPallini 12-Jan-22 5:38am    
5.
Member 14036158 12-Jan-22 6:13am    
Thanks for the explanation.
It's working.
This is the code you need to find all the elements:
C++
for (auto it = v2.begin (); it != v2.end (); it++) // iterate the elements of v2
{
    auto fit = std::find (v1.begin (), v1.end (), *it); // is the element in v1?
    if (fit != v1.end ())
    {
        std::cout << "Element " << *fit << " found at position : ";
        std::cout << it - v2.begin() << " (counting from zero) \n" ;
    }
    else
    {
        std::cout << "Element " << *it << " not found.\n";

        //remove v2 elements not matched with v1 elements
    }
}

Note that you cannot use v2.erase in the else clause as that will destroy the iterator. You need to make a copy of all the positions that need to be removed, and delete them later when this loop has completed.
 
Share this answer
 
v2
Comments
CPallini 12-Jan-22 5:39am    
5.
Member 14036158 12-Jan-22 6:14am    
Thanks Richard for the explanation.
It's working.
Try also
C++
#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
  vector < string > v1 ={"str1"};
  vector < string > v2 ={"str2", "str1", "str3"};

  auto not_in_v1 = [&v1](const string & s) { return find(v1.begin(), v1.end(), s ) == v1.end(); };

  v2.erase( remove_if( v2.begin(), v2.end(), not_in_v1), v2.end() );

  for (auto s : v2)
    cout << s << " " << endl;

   return 0;
}
 
Share this answer
 
Comments
Richard MacCutchan 12-Jan-22 5:32am    
+5 for an elegant solution.
CPallini 12-Jan-22 5:39am    
Thank you!
_Asif_ 12-Jan-22 6:04am    
+5
Member 14036158 12-Jan-22 6:15am    
Thanks for the explanation.
It's working.
CPallini 12-Jan-22 6:29am    
You are welcome.
"It's working"
Did you really doubt? :-D

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900