乐趣区

关于c++:C-STL-set容器

一、前言

和 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;}

后果如下:

退出移动版