集合 set
std::set
的一些标准库函数如下:
- 构造函数:
set()
:默认构造函数,创建一个空的 set 容器。set(const set& other)
:复制构造函数,创建一个相同的 set 集合。效果等同于set1=set2
。set(set&& other) noexcept;
:移动构造函数,将一个 set 集合的内容移动到新的 set 集合中,原先的 set 集合变为空,避免了深层拷贝。set(InputIterator first, InputIterator last)
:用迭代器范围[first, last)
的元素来初始化 set 容器,并自动进行排序+去重。set(std::initializer_list<value_type> ilist)
:使用初始化列表初始化一个 set 容器,自动进行排序+去重。
// 创建一个整数数组
int arr[] = {
50, 20, 20, 40, 10};
// 使用 set 构造函数,从数组范围 [arr, arr+5) 初始化 set 容器
std::set<int> mySet(arr, arr + 5);
// 使用初始化列表来初始化一个 std::set
std::set<int> myset2 = {
50, 20, 30};
// 使用移动构造函数将 myset2 移动到 myset3 , myset2 变为空.
std::set<int> myset3 = std::move(myset2);
- 容器大小和判断:
size()
:返回 set 容器中元素的个数。empty()
:检查 set 容器是否为空,返回布尔值。
- 插入和删除元素:
insert(const value_type& value)
:插入一个新元素到 set 容器中。insert(InputIterator first, InputIterator last)
:插入范围[first, last)
的元素到 set 容器中。insert(std::initializer_list<value_type> ilist)
:使用初始化列表插入元素到std::multiset
容器中。
std::set<int> myset = {
50, 20, 30};
// 使用 insert 函数插入更多元素到 std::set 中
myset.insert({
10, 40, 20, 50});
// 创建一个 vector,并插入一些元素
std::vector<int> myVector = {
10, 40, 20, 50};
// 使用 insert 函数将 vector 中的元素插入到 set 中
mySet.insert(myVector.begin(), myVector.end());
erase(const value_type& value)
:删除指定值的元素。erase(iterator position)
:删除迭代器指向的元素。erase(iterator first, iterator last)
:删除指定范围内的元素。clear()
:清空 set 容器中的所有元素。
std::set<int> mySet = {
10, 20, 30, 40, 50};
// 删除值为 20 的元素
mySet.erase(20);
// 查找值为 30 的元素的迭代器
std::set<int>::iterator it = mySet.find(30);
// 如果找到了元素,则删除该元素
if (it != mySet.end()) {
mySet.erase(it);
}
- 查找元素:
find(const value_type& value)
:查找具有给定值的元素,返回一个迭代器,如果找不到则返回end()
。count(const value_type& value)
:返回具有给定值的元素的数量,对于std::set
容器来说,该函数返回值只能是 0 或 1,因为键是唯一的。lower_bound(const value_type& value)
:返回一个指向第一个不小于给定值的元素的迭代器。upper_bound(const value_type& value)
:返回一个指向第一个大于给定值的元素的迭代器。prev(const value_type& value)
:返回一个指向第一个小于给定值的元素的迭代器。equal_range(const value_type& value)
:返回一个范围,其中的元素与给定值相等,即返回一个 pair,包含lower_bound
和upper_bound
的迭代器。
#include <iostream>
#include <set>
int main() {
std::set<int> mySet = {
10, 20, 30, 40, 50};
int targetValue = 35;
std::set<int>::iterator it = mySet.lower_bound(targetValue);
if (it != mySet.end()) {
std::cout << "Element " << *it << " found." << std::endl; //输出:Element 40 found.
} else {
std::cout << "Element not found." << std::endl;
}
it = mySet.upper_bound(targetValue);
if (it != mySet.end()) {
std::cout << "Element " << *it << " found." << std::endl; //同样输出:Element 40 found.
} else {
std::cout << "Element not found." << std::endl;
}
// 类型为:std::pair<std::set<int>::iterator, std::set<int>::iterator>
auto range = mySet.equal_range(targetValue);
if (range.first != range.second) {
std::cout << "Element " << *range.first << " found." << std::endl;
}
else {
std::cout << "Element not found." << std::endl;
}
return 0;
}
- 迭代器相关:
begin()
:返回指向 set 容器中第一个元素的迭代器。end()
:返回指向 set 容器中最后一个元素后面位置的迭代器。rbegin()
:返回指向 set 容器中最后一个元素的反向迭代器。rend()
:返回指向 set 容器中第一个元素前面位置的反向迭代器。
- 算法操作
swap(set_type& other)
:可以用来交换两个set
容器的内容。用法示例,set1.swap(set2);
,交换后的两个容器会互相交换它们的元素,且仍然保持有序。merge(set_type& other)
:将另一个set
容器的内容合并到当前容器中。要求两个容器都已经有序。intersection(set_type& other)
:在当前set
容器和另一个容器之间进行交集操作,结果保存在当前容器中。difference(set_type& other)
:在当前set
容器和另一个容器之间进行差集操作,结果保存在当前容器中。
关联容器的顺序程序员不能修改,因此无法进行排序
sort()
和反转reverse()
等操作。
映射 map
std::map
是 C++ 标准库中的关联容器,它提供了一种映射关系,将键和值进行关联。std::map
中的元素是按照键值进行有序存储的,并且每个键都是唯一的。下面是 std::map
的标准库函数:
- 构造函数:
map()
:默认构造函数,创建一个空的std::map
。map(const map& other)
:复制构造函数,用另一个std::map
对象初始化当前对象。map(map&& other) noexcept
:移动构造函数,从一个右值引用的std::map
对象移动构造当前对象。map(std::initializer_list<value_type> ilist)
:使用初始化列表插入元素初始化std::map
。
- 赋值运算符:
map& operator=(const map& other)
:复制赋值运算符,将另一个std::map
的内容赋值给当前对象。map& operator=(map&& other) noexcept
:移动赋值运算符,从一个右值引用的std::map
对象移动赋值给当前对象。map& operator=(std::initializer_list<value_type> ilist)
:使用初始化列表插入元素赋值给std::map
。
- 容器大小和判断:
size()
:返回 map 容器中元素的个数。empty()
:检查 map 容器是否为空,返回布尔值。
- 插入和删除元素:
iterator insert(const value_type& value)
:插入一个键值对(std::pair
)到std::map
中。iterator insert(iterator hint, const value_type& value)
:在提示位置插入一个键值对到std::map
中。iterator insert(iterator hint, value_type&& value)
:在提示位置插入一个移动构造的键值对到std::map
中。iterator insert(std::initializer_list<value_type> ilist)
:使用初始化列表插入元素到std::map
容器中。
// 使用 insert() 插入键值对
myMap.insert(std::make_pair(1, "One"));
// 使用 insert() 在提示位置插入一个键值对
auto hint = myMap.find(2); // 查找键为 2 的位置作为提示位置
if (hint != myMap.end()) {
myMap.insert(hint, std::make_pair(4, "Four")); // 插入到了键 2 之后
}
// 使用初始化列表插入键值对
myMap.insert({
{
5, "Five"},
{
6, "Six"}
});
// 通过 [key] 下标访问,实现插入键值对
myMap[7] = "seven";
通过 [ key ] 下标访问,可以实现最简单最常用的键值对插入/修改 value 的方式!
void erase(iterator position)
:删除指定迭代器位置的键值对。size_type erase(const key_type& key)
:删除指定键值对应的元素。
std::map<int, std::string> myMap;
myMap[1] = "one";
myMap[2] = "two";
myMap[3] = "three";
// 删除键为2的元素
auto it = myMap.find(2);
if (it != myMap.end()) {
myMap.erase(it);
}
// 删除键为2的元素,并检查删除的数量
size_t count = myMap.erase(2);
if (count > 0) {
std::cout << "Deleted " << count << " element(s)." << std::endl;
}
void clear()
:删除所有元素,使std::map
变为空。
- 查找和访问元素:
iterator find(const key_type& key)
:返回指向给定键值的元素的迭代器,如果未找到则返回end()
。const_iterator find(const key_type& key) const
:const
版本的find()
,用于在const
对象上查找元素。size_type count(const key_type& key) const
:返回具有给定键值的元素的数量(在std::map
中要么是 0,要么是 1)。mapped_type& operator[](const key_type& key)
:访问给定 key 键对应的值;如果给定的 key 键不存在,则会给该 key 键插入一个默认值 0 ,并返回一个引用(此时为 0)。mapped_type& operator[](key_type&& key)
:与上面类似,但用于移动构造的键值。
- 迭代器相关:
iterator begin()
:返回指向第一个元素的迭代器。iterator end()
:返回指向最后一个元素的下一个位置的迭代器。const_iterator begin() const
:const
版本的begin()
,用于在const
对象上获取迭代器。const_iterator end() const
:const
版本的end()
,用于在const
对象上获取迭代器。rbegin()
,rend()
:返回指向反向的迭代器。通过
first
和second
,访问迭代器中的 key 值和 value 值。
map <int, int> m1;
// 添加元素 ···
for (auto it = m1.begin( ); it != m1.end( ); it++ )
cout << it->first << " " << it->second <<endl;
}
多重集合/映射
std::set
和 std::multiset
,std::map
和 std::multimap
,它们的区别主要体现在元素的唯一性上。
元素的唯一性
std::set
:要求容器中的元素是唯一的,即不允许有重复的元素存在。当你尝试插入一个已经存在的元素时,插入操作不会生效,容器的大小也不会发生改变。std::map
:要求容器中的键是唯一的,即在一个std::map
中,每个键只能对应一个值。当插入一个已经存在的键时,旧的键值对会被覆盖。std::multiset
,std::multimap
:允许容器中有重复的元素/键值对。即使元素已经存在,你仍然可以插入相同的元素,容器会维护多个相同的键值。
除了上述区别外,std::set
和 std::multiset
,std::map
和 std::multimap
的标准库函数在大部分情况下是相同的。