Given an STL vector, output only the duplicates in sorted order, e.g.,
INPUT : { 4, 4, 1, 2, 3, 2, 3 }
OUTPUT: { 2, 3, 4 }
The algorithm is
This is in the style of the standard library. Credit for algorithm goes to James! (If you +1 me, you better +1 him, or else). All I did was make it standard library style:
#include
#include
#include
#include
#include
// other stuff (not for you)
template
void print(const char* pMsg, const T& pContainer)
{
std::cout << pMsg << "\n ";
std::copy(pContainer.begin(), pContainer.end(),
std::ostream_iterator(std::cout, " "));
std::cout << std::endl;
}
template
T* endof(T (&pArray)[N])
{
return &pArray[0] + N;
}
// not_unique functions (for you)
template
ForwardIterator not_unique(ForwardIterator pFirst, ForwardIterator pLast,
BinaryPredicate pPred)
{
// correctly handle case where an empty range was given:
if (pFirst == pLast)
{
return pLast;
}
ForwardIterator result = pFirst;
ForwardIterator previous = pFirst;
for (++pFirst; pFirst != pLast; ++pFirst, ++previous)
{
// if equal to previous
if (pPred(*pFirst, *previous))
{
if (previous == result)
{
// if we just bumped bump again
++result;
}
else if (!pPred(*previous, *result))
{
// if it needs to be copied, copy it
*result = *previous;
// bump
++result;
}
}
}
return result;
}
template
ForwardIterator not_unique(ForwardIterator pFirst, ForwardIterator pLast)
{
return not_unique(pFirst, pLast,
std::equal_to());
}
//test
int main()
{
typedef std::vector vec;
int data[] = {1, 4, 7, 7, 2, 2, 2, 3, 9, 9, 5, 4, 2, 8};
vec v(data, endof(data));
// precondition
std::sort(v.begin(), v.end());
print("before", v);
// duplicatify (it's a word now)
vec::iterator iter = not_unique(v.begin(), v.end());
print("after", v);
// remove extra
v.erase(iter, v.end());
print("erased", v);
}