我重新做了Nate Kohl的分析并得到不同的结果。对于我的测试案例,直接对向量进行排序始终比使用集合更有效率。我添加了一个新的更高效的方法,使用 unordered_set
。
请记住,unordered_set
方法仅在您拥有适用于需要去重和排序的类型的良好哈希函数时才有效。对于整数,这很容易!(标准库提供了一个默认哈希,即恒等函数。)此外,不要忘记在最后进行排序,因为无序集合是无序的:)
我深入研究了 set
和 unordered_set
的实现,并发现构造函数实际上会为每个元素构造一个新的节点,然后检查其值以确定是否应将其插入(至少在 Visual Studio 实现中如此)。
以下是5种方法:
f1: 只使用 vector
,sort
+ unique
sort( vec.begin(), vec.end() );
vec.erase( unique( vec.begin(), vec.end() ), vec.end() );
f2: 转换为set
(使用构造函数)
set<int> s( vec.begin(), vec.end() );
vec.assign( s.begin(), s.end() );
f3: 手动转换为 set
类型
set<int> s;
for (int i : vec)
s.insert(i);
vec.assign( s.begin(), s.end() );
f4:转换为unordered_set
(使用构造函数)
unordered_set<int> s( vec.begin(), vec.end() );
vec.assign( s.begin(), s.end() );
sort( vec.begin(), vec.end() );
f5: 将代码手动转换为unordered_set
unordered_set<int> s;
for (int i : vec)
s.insert(i);
vec.assign( s.begin(), s.end() );
sort( vec.begin(), vec.end() );
我用一个包含1亿个int类型的向量进行了测试,这些整数是在区间[1,10]、[1,1000]和[1,100000]中随机选择的。
结果如下(时间以秒为单位,数字越小表示速度越快):
range f1 f2 f3 f4 f5
[1,10] 1.6821 7.6804 2.8232 6.2634 0.7980
[1,1000] 5.0773 13.3658 8.2235 7.6884 1.9861
[1,100000] 8.7955 32.1148 26.5485 13.3278 3.9822