If you want to remove the duplicate while keeping the order of the elements, you can do it (inplace) in O(n log(n))
like this:
std::vector<std::string> v{"one", "two", "three", "two", "ten", "six", "ten"};
// Occurrence count
std::map<std::string, int> m;
auto it = std::copy_if(v.cbegin(), v.cend(), v.begin(),
[&m](std::string const& s) { return !m[s]++; });
// ^ keep s if it's the first time I encounter it
v.erase(it, v.end());
Explanation: m
keeps track of the number of times each string has already been encountered while scanning through v
. The copy_if
won't copy a string if it has already been found.
If you want to remove all the elements that are duplicated, you can do it (inplace) in O(n log(n))
like this:
// Occurrence count
std::map<std::string, int> m;
// Count occurrences of each string in v
std::for_each(v.cbegin(), v.cend(), [&m](std::string const& s) { ++m[s]; } );
// Only keep strings whose occurrence count is 1.
auto it = std::copy_if(v.cbegin(), v.cend(), v.begin(),
[&m](std::string const& s) { return m[s] == 1; });
v.erase(it, v.end());