文章参考文献:cplusplus
博主:拖拉机厂第一代码手
gitee:拖拉机厂第一代码手
c++专栏:C++
set是一种按照一定次序存储元素的容器。在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改,但是可以从容器中插入或删除它们。
在内部,set中的元素总是按照其内部比较对象所指示的特定严格弱排序准则进行排序。这意味着set中的元素是有序的,可以根据排序准则进行访问和操作。
set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。这使得set在需要有序存储和操作元素的场景中非常有用。
set在底层是用二叉搜索树(红黑树)实现的。这种数据结构保证了插入、删除和查找操作的平均时间复杂度都是O(log n),使得set具有高效的性能。
总的来说,set是一种有序、唯一的容器,适用于需要按照一定顺序存储和操作元素的场景。它提供了丰富的成员函数和迭代器,方便对元素进行插入、删除、查找和遍历操作。
可以根据需要自定义这些模板参数,例如指定自定义的比较函数或分配器。
set类提供了多个构造函数,可以根据不同的需求进行对象的初始化。以下是常用的构造函数:
set (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
创建一个空的set对象。
set (InputIterator first, InputIterator last,
const Compare& comp = Compare(), const Allocator& = Allocator() );
使用范围 [first, last) 内的元素初始化set对象。要求元素类型必须支持复制构造函数。
set (const set& x);
使用另一个set对象x中的元素创建一个新的set对象。
需要注意的是,C++98标准中没有提供移动构造函数和初始化列表构造函数。如果需要使用移动构造函数、初始化列表构造函数或者自定义比较函数和分配器的版本,可以考虑使用C++11及更高版本的标准库。
set类提供了多种迭代器,用于遍历容器中的元素。以下是set的迭代器类型:
iterator:用于遍历set中的元素,并且可以修改元素的值。
const_iterator:用于遍历set中的元素,但不能修改元素的值。
这两种迭代器都支持前向遍历,即可以使用++操作符将迭代器指向下一个元素。
set类提供了以下成员函数来获取迭代器的起始和结束位置:
函数 | 含义 |
---|---|
begin() | 返回一个迭代器,指向set中第一个元素的位置。 |
end() | 返回一个迭代器,指向set中最后一个元素之后的位置。 |
rbegin() | 返回一个逆向迭代器,指向set中最后一个元素的位置。 |
rend() | 返回一个逆向迭代器,指向set中第一个元素之前的位置。 |
使用set的迭代器可以进行遍历、访问和修改元素的操作。例如,可以使用迭代器来遍历set中的元素并打印它们的值:
set<int> mySet = {1, 2, 3, 4, 5};
// 使用迭代器遍历并打印元素
for (set<int>::iterator it = mySet.begin(); it != mySet.end(); ++it) {
cout << *it << " ";
}
需要注意的是,set中的元素是按照升序排列的,因此使用迭代器遍历时会按照升序顺序访问元素。
另外,set还提供了reverse_iterator和const_reverse_iterator类型的迭代器,用于逆向遍历set中的元素。可以使用rbegin()和rend()成员函数获取逆向迭代器的起始和结束位置。例如:
set<int> mySet = {1, 2, 3, 4, 5};
// 使用逆向迭代器遍历并打印元素
for (set<int>::reverse_iterator rit = mySet.rbegin(); rit != mySet.rend(); ++rit) {
cout << *rit << " ";
}
这样会按照降序顺序访问set中的元素。
需要注意的是,end()和rend()返回的迭代器并不指向set中的有效元素,而是指向最后一个元素之后的位置。因此在遍历时,通常使用!=来判断迭代器是否到达结束位置。
set类提供了一些成员函数来获取容器的容量信息。以下是set的容量相关的成员函数:
size():返回set中元素的个数。
empty():检查set是否为空,如果为空则返回true,否则返回false。
max_size():返回set对象能够容纳的最大元素数量。
这些成员函数可以用于获取set的容量信息。例如,可以使用size()函数获取set中元素的个数:
set<int> mySet = {1, 2, 3, 4, 5};
cout << "Size of set: " << mySet.size() << endl;
可以使用empty()函数检查set是否为空:
set<int> mySet;
if (mySet.empty()) {
cout << "Set is empty" << endl;
} else {
cout << "Set is not empty" << endl;
}
这些函数对于判断set是否为空或者获取set中元素的个数非常有用。
另外,set类还提供了一个成员函数max_size(),用于返回set对象能够容纳的最大元素数量。max_size()函数返回的是一个整数,表示set对象能够容纳的最大元素数量。这个值取决于操作系统和编译器的限制。
set<int> mySet;
cout << "Maximum size of set: " << mySet.max_size() << endl;
需要注意的是,max_size()返回的是一个理论上的最大值,实际上可能由于系统资源限制而无法达到这个值。因此,在使用set时应该根据实际情况进行内存和资源的管理。
set容器是一种有序的容器,不允许直接修改容器中的元素值。这是因为set容器中的元素是根据其值进行排序的,直接修改元素的值可能导致元素的顺序发生改变,破坏了set容器的有序性。
然而,可以使用erase()函数删除set容器中的元素,然后使用insert()函数插入一个新的元素来实现间接的修改操作。
set容器提供了以下成员函数用于插入、删除、交换和清空元素:
insert(value):将value插入set中。
insert (position, value):将value插入到position的位置。
insert(first, last):将[first, last)范围内的元素插入set中。
erase(value):删除set中与value相等的元素。
erase(iterator):删除迭代器指向的元素。
erase(first, last):删除[first, last)范围内的元素。
swap(set1, set2):交换set1和set2的内容。
以下是一个示例代码,演示了如何使用这些成员函数:
#include
#include
int main()
{
std::set<int> mySet;
// 插入元素
mySet.insert(5);
mySet.insert(3);
mySet.insert(8);
// 删除元素
mySet.erase(3);
// 交换容器内容
std::set<int> anotherSet;
anotherSet.insert(10);
anotherSet.insert(20);
mySet.swap(anotherSet);
// 清空容器
mySet.clear();
return 0;
}
map是C++标准库中的关联容器之一,它提供了一种以键值对(Key-Value)形式存储和访问元素的方式。map容器中的元素是按照键的顺序进行排序的,并且每个键只能出现一次。
特点:
map中的元素是按照键的顺序进行排序的,默认情况下是按照键的升序排列。
在map中,键值(key)通常用于排序和唯一标识元素,而值(value)存储与键值关联的内容。键值和值的类型可以不同,但在map内部,键值和值通过成员类型value_type绑定在一起,取别名为pair
map中的元素是自动根据键进行排序的,因此可以通过键快速查找、插入和删除元素。
map支持下标访问符([]),可以通过键值获取对应的值。
map通常是基于红黑树实现的,因此插入、删除和查找操作的平均时间复杂度为O(log N),其中N是map中元素的数量。
map容器提供了多个构造函数,可以根据不同的需求来创建map对象。以下是一些常用的构造函数:
map (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
创建一个空的map对象。
map (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
使用[first, last)范围内的元素来构造map对象。要求范围内的元素类型必须能够隐式转换为std::pair
。
map (const map& x);
使用另一个map对象otherMap中的元素来构造新的map对象。
map类提供了多种迭代器,用于遍历容器中的元素。以下是map的迭代器类型:
iterator:用于遍历map中的元素,并且可以修改元素的值。
const_iterator:用于遍历map中的元素,但不能修改元素的值。
这两种迭代器都支持前向遍历,即可以使用++操作符将迭代器指向下一个元素。
map迭代器的常用操作有:
下面是一个示例代码,展示了如何使用map迭代器以及一些常用的函数操作:
#include
#include
using namespace std;
int main()
{
map<string, string> translate{ make_pair("apple", "苹果"), make_pair("banana", "香蕉"), make_pair("bear", "梨")};
// 使用迭代器遍历translate
cout << "正向遍历" << endl;
map<string, string>::iterator it;
for (it = translate.begin(); it != translate.end(); ++it) {
cout << "Key: " << it->first << ", Value: " << it->second << endl;
}
//使用逆向迭代器遍历translate
cout << "逆向遍历" << endl;
map<string, string>::reverse_iterator rit;
for (rit = translate.rbegin(); rit != translate.rend(); ++rit) {
cout << "Key: " << rit->first << ", Value: " << rit->second << endl;
}
return 0;
}
map提供了一些方法来获取容器的容量信息,下面是关于map容量和元素访问的一些常用方法:
map<int, string> myMap{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
if (myMap.empty()) {
cout << "Map is empty" << endl;
}
else {
cout << "Map is not empty" << endl;
}
map<int, string> myMap{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
cout << "Map size: " << myMap.size() << endl;
map<int, string> myMap{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
cout << "Max map size: " << myMap.max_size() << endl;
map提供了多种方法来修改容器中的元素,以下是一些常用的map修改操作方法:
map<int, string> myMap;
myMap.insert(make_pair(1, "apple")); // 插入键值对
myMap.insert(pair<int, string>(2, "bear"));
myMap.insert(map<int, string>::value_type(3, "banana"));
如果插入的键已经存在于map中,insert函数不会更新该键对应的值。
map<int, string> myMap{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
myMap.erase(2);
map<int, string> myMap1{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
map<int, string> myMap2{ make_pair(1, "apple"), make_pair(2, "banana"), make_pair(3, "bear") };
myMap1.swap(myMap2);
map<int, string> myMap{ make_pair(1, "apple"), make_pair(2, "banana"), make_pair(3, "bear") };
// 填充myMap的内容
myMap.clear(); // 清空myMap中的所有键值对
map提供了一些方法来查找元素和访问元素的值。
以下是关于map的find、count和operator[]方法的介绍:
map<int, string> myMap{make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c")};
map<int, string>::iterator it = myMap.find(2);
if (it != myMap.end()) {
cout << "Found: " << it->second << endl;
}
else {
cout << "Not Found" << endl;
}
map<int, string> myMap{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
int count = myMap.count(2);
if (count > 0) {
cout << "Element exists" << endl;
}
else {
cout << "Element does not exist" << endl;
}
map<int, string> myMap{ make_pair(1, "a"), make_pair(2, "b"), make_pair(3, "c") };
string value1 = myMap[2];
string value2 = myMap[4];
cout << "Value at key 2: " << value1 << endl;
cout << "Value at key 4: " << value2 << endl;
需要注意的是,使用operator[]方法访问不存在的键时,会自动插入一个新的键值对到map中,这可能会改变map的大小。
C++中的map和set是标准库中的两个关联容器,它们都提供了高效的数据存储和检索功能。下面是对map和set的文章总结:
map:
set:
map和set都是非常有用的容器,可以在许多场景下使用。它们提供了高效的数据存储和检索功能,并且保持了元素的有序性和唯一性。在需要存储键值对或需要快速查找和删除元素的情况下,map和set都是不错的选择。
最后,如果觉得文章对你有帮助的话就来一个大大的吧。