一、前言
和 map、multimap 容器不同,应用 set 容器存储的各个键值对,要求键 key 和值 value 必须相等。如下:
{<'a', 'a'>, <'b', 'b'>, <'c', 'c'>}
不反对存储键和值不相等的键值对。因而在应用 set 容器时,只须要为其提供各键值对中的 value 值即可。set 容器和 map 容器一样,会自行依据键的大小对存储的键值对进行排序,在 set 容器中,实际上也是依据 value 值进行排序。
set 容器存储的各个元素的值 必须各不相同 。须要留神的是:在语法上 set 容器并没有强制对存储元素的类型做 const 润饰,因而set 容器中存储的元素的值是能够批改的。然而,C++ 规范为了避免用户批改容器中元素的值,对所有可能会实现此操作的行为做了限度,使得 在失常状况下,用户是无奈做到批改 set 容器中元素的值的 。
留神:间接批改 set 容器中的已存储的元素的值,可能会毁坏 set 容器中元素的有序性。最正确的批改 set 容器中元素值的做法是:先删除该元素,而后再增加一个批改后的元素。应用 set 容器,须要
#include <set>
1、set 容器类模板的定义
template < class T, // 键 key 和值 value 的类型
class Compare = less<T>, // 指定 set 容器外部的排序规定
class Alloc = allocator<T> // 指定分配器对象的类型
> class set;
因为键和值的类型是一样的,因而这里只有 3 个参数,大多数状况下,主须要用到其中的前 2 个参数。
二、创立 set 容器的办法
常见的创立 set 容器的办法,大抵有以下 5 种。
①std::set<std::string> myset;
②std::set<std::string> myset{"1","2","3"};
③std::set<std::string> copyset(myset);
④std::set<std::string> myset{"1","2","3"};
std::set<std::string> copyset(++myset.begin(), myset.end());
⑤std::set<std::string,std::greater<string> > myset{"1","2","3"};
①默认构造函数,创立空的 set 容器,会对存储的 string 类型元素做升序排序
②在创立 set 容器的同时,对其进行初始化
③通过拷贝(复制)构造函数,实现在创立新 set 容器的同时,将已有 set 容器中存储的所有元素全副复制到新 set 容器中,等价于 std::set<std::string> copyset = myset;C++ 11 规范还为 set 类模板新增了挪动构造函数,其性能是实现创立新 set 容器的同时,利用长期的 set 容器为其初始化,如下:
set<string> retSet()
{std::set<std::string> myset{ "1","2","3"};
return myset; // 返回值是一个长期 set 容器,因而在初始化 copyset 容器时,其外部调用的是 set 类模板中的挪动构造函数,而非拷贝构造函数。}
std::set<std::string> copyset(retSet());
// 等价于 std::set<std::string> copyset = retSet();
④set 类模板取已有 set 容器中的局部元素,来初始化新 set 容器
⑤、批改 set 容器中的排序规定形式
三、办法
这里不列举迭代器、插入和删除相干的办法。
办法 | 性能 |
---|---|
empty() | 若容器为空,则返回 true;否则 false |
size() | 返回以后 set 容器中存有元素的个数 |
max_size() | 返回 set 容器所能包容元素的最大个数,不同的操作系统,其返回值亦不雷同 |
count(val) | 在以后 set 容器中,查找值为 val 的元素的个数,并返回。留神,因为 set 容器中各元素的值是惟一的,因而该函数的返回值最大为 1 |
四、实例
1、创立 set 容器
形式 1
std::set<std::string> myset;
std::cout << "myset size:" << myset.size() << std::endl;
形式 2
std::set<std::string> myset1{
"who are you",
"i am lin",
"i am wu",
"i am ouyang"};
std::cout << "myset1 size:" << myset1.size() << std::endl;
std::set<std::string>::iterator setIter = myset1.begin();
for (; setIter != myset1.end(); setIter++)
{std::cout << "myset1 :" << *setIter << std::endl;}
形式 3
std::set<std::string> myset2(myset1);
std::cout << "myset2 size:" << myset2.size() << std::endl;
setIter = myset2.begin();
for (; setIter != myset2.end(); setIter++)
{std::cout << "myset2 :" << *setIter << std::endl;}
挪动构造函数形式
set<string> RemoveStructureSet()
{
std::set<std::string> myset{
"who are you",
"i am wen",
"i am li" };
return myset;
}
std::set<std::string> myset3(RemoveStructureSet());
// 等价于 std::set<std::string> myset3 = RemoveStructureSet();
setIter = myset3.begin();
for (; setIter != myset3.end(); setIter++)
{std::cout << "myset3 :" << *setIter << std::endl;}
形式 4
std::set<std::string> myset4(++myset.begin(), --myset.end());
setIter = myset4.begin();
for (; setIter != myset4.end(); setIter++)
{std::cout << "myset4 :" << *setIter << std::endl;}
形式 5
std::set<std::string, std::greater<string> > myset5{
"who are you",
"i am lin",
"i am wu",
"i am ouyang" };
setIter = myset5.begin();
for (; setIter != myset5.end(); setIter++)
{std::cout << "myset5 :" << *setIter << std::endl;}
后果如下: