C++ STL中的unordered_multiset swap()
unordered_multiset
是C++ STL中的一个关联容器,它的元素没有顺序,并且可以存储重复值。而swap()是C++ STL中的一个关键字,可以在不消耗额外空间的情况下交换两个变量的值。在unordered_multiset中,swap()可以帮助我们优化程序的性能,下面将详细介绍。
unordered_multiset简介
在使用unordered_multiset之前,我们先来了解一下该容器的一些基础知识。
1. 什么是unordered_multiset?
unordered_multiset
是一个没有顺序的、可以重复的容器。它是一个哈希表,通过散列函数对元素进行分类,然后存储在不同的桶中。通常情况下,用户需要提供一个哈希函数用来对元素进行分类。
2. unordered_multiset的优缺点
- 优点:元素可以重复、查找元素速度非常快
- 缺点:无序、不能使用下标访问元素、迭代器失效的可能性大
3. unordered_multiset的运算符和方法
- =:重载赋值运算符
- insert():插入元素
- emplace():在容器中构造一个新元素
- erase():从容器中删除元素
- clear():清空容器
- size():返回元素个数
- empty():判断容器是否为空
- find():查找指定元素
- count():统计指定元素的数量
swap()的介绍
swap()
是C++ STL中的一个关键字,可以在不占用额外空间的情况下,交换两个相同数据类型的变量的值。由于swap()
可以大大优化程序性能,它很重要。
1. swap()的使用
在unordered_multiset中,swap()函数可以用来交换两个unordered_multiset容器中元素的值。其用法如下:
void swap(unordered_multiset& other);
例如,下面的代码展示了如何交换两个unordered_multiset的值。
unordered_multiset<int> foo = {1,2,3};
unordered_multiset<int> bar = {4,5,6};
foo.swap(bar);
// 现在,foo是{4,5,6},而bar是{1,2,3}
2. swap()的时间复杂度
我们可以发现,swap()
函数不需要额外开辟空间,简单地交换两个数据类型变量的值。因此,它的时间复杂度是O(1)。
unordered_multiset swap()的优化
在容器中,一些性能低下的操作可能会导致程序效率降低,因此,我们需要一些工具来帮助我们提高程序的性能。unordered_multiset中的swap()就是为此而诞生的。下面我们来看看它是如何提高程序性能的。
1. swap()和拷贝构造函数的比较
由于unordered_multiset是一个哈希表,它在内存中保存了一个已经分配好的桶(vector容器),这些桶在容器初始化时就已经被分配好。当我们将两个unordered_multiset容器互换时,它们的内部桶以及桶中的元素都会被交换。这使得我们在交换unordered_multiset容器的值时,不需要多余的内存空间。
与之相比,通过类似以下代码手动进行拷贝时,需要消耗额外的内存空间:
void swap(unordered_multiset& first, unordered_multiset& second){
unordered_multiset temp = first;
first = second;
second = temp;
}
该代码中,我们需要先创建一个临时unordered_multiset对象,然后把first容器中的内容拷贝到临时对象中去,再将second容器中的内容通过赋值运算符拷贝到first容器中,最后将临时对象中的内容通过赋值运算符拷贝到second容器中。
这样的拷贝过程不仅会导致多余的内存分配和销毁,还需要额外的时间和空间开销,导致程序的性能降低。
而swap()函数则可以直接交换两个容器中的值,不需要额外地分配或销毁内存,从而提高程序性能。
2. swap()函数和元素移动的比较
在unordered_multiset容器中,如果要把一个容器的元素移动到另一个容器中,我们可以使用std::move()函数来实现。例如,我们可以使用以下代码将一个unordered_multiset容器中的元素移动到另一个unordered_multiset容器中去:
unordered_multiset<int> source = {1,2,3};
unordered_multiset<int> destination;
std::move(source.begin(), source.end(), std::inserter(destination, destination.begin()));
这会将source中的所有元素移动到destination容器中。这样做可以减少不必要的拷贝操作,提高程序性能。
与元素移动相比,swap()函数更适用于缩短程序运行时间。原因是,在使用std::move()函数进行元素移动时,需要遍历所有元素,并将它们插入到目标容器中。这一过程可能需要更多时间。而使用swap()函数,直接交换两个容器的值,可以更直接地完成操作。
实例演示
下面,我们来演示一下使用swap()函数优化unordered_multiset容器的代码实例:
# include <iostream>
# include <unordered_set>
# include <chrono>
# include <algorithm>
using std::unordered_multiset;
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::microseconds;
int main()
{
unordered_multiset<int> arr1;
unordered_multiset<int> arr2;
// 向arr1中插入10000个随机整数
for (int i = 0; i < 10000; i++) {
arr1.insert(rand() % 10000);
}
// 把arr1中的值移动到arr2中,使用std::move()
auto t1 = high_resolution_clock::now();
std::move(arr1.begin(), arr1.end(), std::inserter(arr2, arr2.begin()));
auto t2 = high_resolution_clock::now();
std::cout << "std::move() 耗时:" << duration_cast<microseconds>(t2 - t1).count() << " 微秒" << std::endl;
// 把arr1和arr2的值交换,使用swap()
t1 = high_resolution_clock::now();
arr1.swap(arr2);
t2 = high_resolution_clock::now();
std::cout << "swap() 耗时:" << duration_cast<microseconds>(t2 - t1).count() << " 微秒" << std::endl;
return 0;
}
在该代码中,我们创建了两个空的unordered_multiset容器arr1和arr2,并向arr1中插入了10000个随机整数。我们使用std::move()函数将arr1中的元素移动到arr2中,并使用swap()函数交换了arr1和arr2的值。我们通过计时器(std::chrono库)来比较这两种方法的耗时。
执行上述代码,可能会得到以下类似结果:
std::move() 耗时:157 毫秒
swap() 耗时:0 微秒
可以看到,使用std::move()函数将arr1中的元素移动到arr2中,耗时约为157毫秒。而使用swap()函数交换arr1和arr2中的值,完全不需要花费额外的时间,耗时为0微秒。
这个例子展示了,当我们需要将一个unordered_multiset容器的值传递给另一个unordered_multiset容器时,使用swap()函数可以大大提高程序的性能。
结论
在C++中,unordered_multiset容器提供了一种基于哈希表的键值存储机制。我们可以通过swap()函数来直接交换unordered_multiset容器中的值,从而提高程序性能。与元素移动相比,swap()函数更适用于缩短程序运行时间。如果您需要将一个unordered_multiset容器的值传递给另一个unordered_multiset容器时,使用swap()函数是一个很好的选择。