我有一个非常大的std :: vector std :: vectors,它包含固定数量的无符号整数。
所有uints向量都按升序排序。
我目前消除重复载体的方法是
unsigned int i = 0;
while ( i < new_combs.size() )
{
unsigned int j = i + 1;
while ( j < new_combs.size() )
{
unsigned int k = 0;
while ( k < new_combs.at(i).size() && new_combs.at(i).at(k) == new_combs.at(j).at(k) )
++k;
if ( k == new_combs.at(j).size() )
new_combs.erase(new_combs.begin() + j);
else
++j;
}
++i;
}
这里,new_combs是一个包含上述向量的向量。
如果向量矢量未排序,是否有更有效的方法来消除重复?
答案 0 :(得分:9)
较短的方法是使用<algorithm>
:
std::sort(new_combs.begin(), new_combs.end());
new_combs.erase(std::unique(new_combs.begin(), new_combs.end()), new_combs.end());
除非您特别需要std::vector
,否则您可以使用std::set
来避免重复。
答案 1 :(得分:3)
你考虑过使用std :: set吗?它是有序的,不允许重复开始。
答案 2 :(得分:2)
如果矢量未排序,您可以做的不多。如果它已排序,您可以使用算法中定义的unique方法:
new_combs.erase(unique(new_combs.begin(), new_combs.end()), new_combs.end());
答案 3 :(得分:0)
您的代码中有几个元素可以响起性能。
首先,您正在使用向量。从向量中删除元素总是很慢。 您可以考虑使用不同的容器(std :: list)或调整代码,以便您没有任何特殊值(例如零或-1)。
其次,您可以使用std :: set或std :: unordered_set来保留已经遇到的值。 这样,你只需要遍历你的矢量一次。
编辑:忘记这个答案了。我误读了这个问题,并认为必须删除重复的值(不是重复的向量)。
尽管如此,对评论给出了一些反应:
答案 4 :(得分:0)
渐近地,您的算法看起来像通常的O(n)实现,因此是最佳的。 (尽管我不理解你使用i
和j
的对角化策略,以及为什么你只删除,但从不移动元素。你的代码非常不清楚。)
但是,您正在复制STL,并且唯一环路的较短版本是:
struct unique {
template <class C>
void operator()( C& c ) {
c.erase( std::unique( c.begin(), c.end() ), c.end() );
}
};
std::for_each( new_combs.begin(), new_combs.end(), unique() );
答案 5 :(得分:0)
我同意Luchian Grigore's answer,但您也可以考虑将整个外部vector
转换为unordered_set
,这是一个O(n)操作,提供的子矢量哈希值也不大不平衡(与排序的平均O(n * log(n))相反)。您甚至可以将指针用于unordered_set
中的子向量,以避免不必要的复制。对于大量数据而言,这可能是一个重要的性能差异。
This example说明了使用自己的哈希函数和指针的基本概念(它处理vector
的{{1}}并使用string
,而不是unordered_map
,但你应该能够很容易地根据你的需要修改它。)