This approach relies on having sorted input vectors, but after that will only do an linear walk through the current and next vectors to be compared, keeping the matching elements in the first vector. It doesn need to do a full search for each element. The algorithm is reasonably container neutral, requiring only forward iterators so will work with vectors, lists, singly linked lists, raw arrays, etc.
The essential building block for this algorithm is a function that removes elements from a sorted range that aren't in a second sorted range. I'm using the std::remove convention of swapping unwanted elements to the end of the range and returning an iterator pointing to start of the unwanted elements. It's O(n + m).
template<class Input1, class Input2>
Input1 inplace_intersection(Input1 first1, Input1 last1, Input2 first2, Input2 last2)
{
using std::swap;
Input1 nextslot(first1);
for( ; first1 != last1; ++first1 )
{
// Skip elements from the second range that are
// smaller than the current element.
while( first2 != last2 && *first2 < *first1 )
++first2;
// Do we have a match? If so keep
if( first2 != last2 && !(*first1 < *first2) )
{
if( first1 != nextslot )
swap( *first1, *nextslot );
++nextslot;
}
}
return nextslot;
}
With this building block you can operate on sorted vectors this.
std::vector<int> initial;
// fill...
std::vector<int>::iterator first = initial.begin(), last = initial.end();
last = inplace_intersection( first, last, scnd.begin(), scnd.end() );
last = inplace_intersection( first, last, thrd.begin(), thrd.end() );
// etc...
initial.erase( last, erase.end() );
If your input vectors aren't sorted, then you can sort them in place if possible, or otherwise create sorted copies.