C++ set
set是C++标准库中的一种关联容器。所谓关联容器就是通过键(key)来读取和修改元素。与map关联容器不同,它只是单纯键的集合。
set 是关联容器的一种,是排序好的集合(元素已经进行了排序)。除了没有单独的键,set 和 multiset 类似,它和 multiset 的差别在于 set 中不能有重复的元素。multiset 的成员函数 set 中也都有。
简介
set是根据关键字进行保存的,通过实值排序,通过实值查找,且set内部不能有重复元素。我们需要注意到,set内部的键值不能随意改变,只能改变实值。其特点:1.高效访问,通过对比map,我们知道两者的数据结构都是红黑树,map分键值对,而set键值即实值,实值即键值。2.set的键值不允许重复,map也不能,但multimap可以。
定义set的模板有4种,其中两种默认使用 less 来对元素排序,另外两种使用哈希值来保存元素。有序 set 的模板定义在 set 头文件中。无序 set 的模板定义在 unordered_set 头文件中。因此有序 set 包含的元素必须支持比较运算,无序 set 中的元素必须支持哈希运算。
有序set和无序set的比较:一般来说,当 set 中有大量元素时,在无序 set 上执行的随机插入和检索操作要比有序 set 快。在有 n 个元素的有序 set 中检索元素的时间复杂度是 logn。在无序 set 中检索元素的平均时间复杂度是常量,这和元素的个数无关,尽管实际性能会受元素哈希操作和内部组织效率的影响。
set 的定义如下:
template < class Key, class Pred = less, class A = allocator > class set {…}
头文件
引用新的头文件#include<set>
#include<iostream>
#include<set>
#include<string>
#include<algorithm>
using namespace std;
构造函数
1.无参构造
语法一:
pair insert( const TYPE &val );
在当前集合中插入val元素,并返回指向该元素的迭代器和一个布尔值来说明val是否成功的被插入了。
void fun(string i)
{
cout << i << endl;
}
void SetConstruct()
{
set<string> st;
st.insert(string("aaa"));
st.insert(string("bbb"));
st.insert(string("ccc"));
st.insert(string("ddd"));
st.insert(string("fff"));
for_each(st2.begin(),st2.end(),fun); // 遍历 //记得加入头文件algorithm
}
输出结果:
下面解释如何返回这个布尔值反应是否插入成功。我们知道set函数不能有重复元素,因此我们可以实验下插入重复元素是否可以
void fun(string i)
{
cout << i << endl;
}
void SetConstruct()
{
pair<set<string>::iterator,bool> pr;
set<string> st;
st.insert(string("aaa"));
pr = st.insert(string("bbb"));
cout << pr.second << endl; //判断是否插入成功
st.insert(string("ccc"));
pr = st.insert(string("bbb")); //再插入一个“bbb”,判断是否插入成功
cout << pr.second << endl;
for_each(st.begin(),st.end(),fun); // 遍历 //记得加入头文件algorithm
}
输出结果:
由此我们看到,第一个插入成功bool为1,第二个因为键值重复导致失败所以为0
语法二:
iterator insert( iterator i, const TYPE &val );
在迭代器i前插入val;
使用迭代器进行插入,迭代器可以++,但是不可以+2,+3之类的;由于set内部会自动排序,不管用迭代器插入到任意位置,set容器也会将其排序,插入到其应有的序列中去
void fun(string i)
{
cout << i << endl;
}
void SetConstruct()
{
set<string> st;
st.insert(string("ccc"));
st.insert(string("aaa"));
st.insert(string("bbb"));
st.insert(string("fff"));
st.insert(string("ddd"));
set<string>::iterator ite = st.begin(); //定义迭代器ite指向st的首个元素
st.insert(ite,"kkk"); //在首位置插入元素“kkk”,但由于其set会自动排序输出结果仍在最后
for_each(st.begin(),st.end(),fun); // 遍历 //记得加入头文件algorithm
}
输出结果:
在这个代码片段中我们是以乱序插入的元素,然而输出以后还是以升序排列。
语法三:
void insert( input_iterator start, input_iterator end );
将迭代器start开始到end结束返回内的元素插入到集合中;
void fun(string i)
{
cout << i << endl;
}
void SetConstruct()
{
set<string> st;
st.insert(string("ccc"));
st.insert(string("aaa"));
st.insert(string("bbb"));
st.insert(string("fff"));
st.insert(string("ddd"));
set<string> st1;
st1.insert(string("ggg"));
st1.insert(string(