If the original order doesn't matter, then the fix is simple. Use a map:
The first loop keeps track of the number of times a number is encountered and saves this info in the map. The second loop then goes through the map that was built and only pushes back items with a "hit count" of 1. If it's more than 1, then the item was seen 2 or more times. But remember, the map will order the items, so if you want to keep the original order, then a different container (a std::vector) can be used instead of std::map.Code:#include <vector>
#include <map>
#include <iostream>
#include <iterator>
#include <algorithm>
template <typename T>
std::vector<T> CreateUniqueVector(T* firstItem, T* lastItem)
{
std::map<T, int> tMap;
std::vector<T> vReturn;
T* curItem = firstItem;
while ( curItem != lastItem )
{
tMap[*curItem]++;
++curItem;
}
typename std::map<T, int>::iterator it = tMap.begin();
while (it != tMap.end() )
{
if (it->second == 1 )
vReturn.push_back(it->first);
++it;
}
return vReturn;
}
Now, if you tried to do this with your "simple" code, you will find very easily that it isn't so simple, especially if the order must be kept. You will wind up doing basically what the code I posted above is doing, but without an official "map" type. More than likely you will find yourself using an array that keeps track of the "hit count", no different than the code above (without the STL), and then going through the array at the end to find out which items showed up more than once.
Here is a solution using std::vector that keeps the order:
The issue with this solution is that it isn't the best performing solution due to the call to std::find each time a number is encountered. But basically, this does the job. It works by seeing if an item is already in the vector. If it is in the vector, the item is erased.Code:template <typename T>
std::vector<T> CreateUniqueVector(T* firstItem, T* lastItem)
{
typename std::vector<T>::iterator it;
std::vector<T> vReturn;
T* curItem = firstItem;
while ( curItem != lastItem )
{
it = std::find(vReturn.begin(), vReturn.end(), *curItem);
if ( it != vReturn.end() )
vReturn.erase(it);
else
vReturn.push_back(*curItem);
++curItem;
}
return vReturn;
}
Regards,
Paul McKenzie