有没有办法在保持顺序的同时从包含字符串元素的向量容器中删除重复元素。
到目前为止,我已经使用了 set 方法,但它不保留顺序。
对于这个问题,我不知道如何使用 remove_if 。
如何使用临时容器:
std::vector< int >::iterator i , j ;
std::set< int > t_set;
for( i = v.begin() , j = v.begin() ; i != v.end() ; ++i )
if( t_set.insert( *i ).second)
*j++ = *i ;
v.erase( j , v.end() );
使用std::remove_if
,我可以想到:
std::set<int> t_set;
std::vector<int> res; //Resultant vector
remove_copy_if(v.begin(), v.end(), std::back_inserter(res),
[&t_set](int x){
return !t_set.insert(x).second;
} );
您可以创建一个空数组,然后遍历原始向量并仅复制向量中每个项目的第一个实例。您可以通过将其添加到集合并在将其添加到新数组之前检查集合中是否存在项目来跟踪您是否已经在向量中看到了一个项目。
你可以这样做:
std::vector<int> v = { 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 8 };
// 1 2 2 3 4 5 6 7 8 9 8
for(size_t i=0;i<v.size();i++)
{
for(size_t j=0;j<v.size();j++)
{
if(v[i] == v[j] && i != j)
{
v.erase(v.begin()+j);
j--; // Fix for certain datasets ie:
} // 1 2 1 1
}
}
// Produces:
// 1 2 3 4 5 6 7 8 9
一个简单的解决方案
std::vector<int>::iterator it;
it = std::unique (myvector.begin(), myvector.end());
此迭代器将指向最后一个元素旁边的元素。如果不需要,您可能不会使用此迭代器。
请参阅此以获取更多参考
编辑:
正如我认为向量会被排序,新的解决方案可能是:
vector<int> vec= {5,1,2,3,5,4,2,1,1,4,3,2,4,5,2,1,3,5,2,3,5,2,3,2,3,5,2,1,3};
set<int> s;
vector<int>::iterator vecIter=vec.begin();
vector<int>::iterator vecIterCopy;
for(;vecIter!=vec.end(); vecIter++)
{
if(s.find(*vecIter)==s.end())
{
s.insert(*vecIter);
*vecIterCopy++ = *vecIter;
}
}
O(n*log(n)) 解决方案:
vector<string> V={"aa","bb","aa","cc","cc"};
set<string> S;
auto i=V.begin();
auto j=i;
for(; i!=V.end(); ++i) {
if(S.insert(*i).second && i!=j++)
*j = std::move(*i);
}
V.erase(j,V.end());
还修改了 POW 的版本std::remove_copy_if
。但这里没有多余的临时:
set<string> S;
V.erase(
copy_if(
make_move_iterator(V.begin()),
make_move_iterator(V.end()),
V.begin(),
[&](const string& x){ return S.insert(x).second;}
),
V.end()
);