C++ set和multiset容器的使用
我们应该知道 set 与 multiset 的区别在于是否允许有重复元素,其他用法都很相似,因此将这两种容器放在一起讲解。
下面讲解 set 和 multiset 的常用方法。
下面分别用这五种方式创建 set 容器,示例代码如下所示:
greater<T>、less<T> 是 STL 中定义的函数对象,包含在 functional 头文件中。
multiset 容器的创建方式与 set 容器相同,示例代码如下所示:
set 与 multiset 的迭代用法与 vector 迭代器相同。
insert() 函数主要有三种重载形式,分别如下所示:
1) 第一种形式的 insert() 函数将元素 elem 插入容器中。对于 set 容器,第一种形式的 insert() 函数调用的返回值是一个 pair<iterator,bool>对象。pair<iterator,bool> 对象的第一个参数 iterator 是迭代器,指示元素插入的位置;
第二个参数 bool 类型的值代表元素是否插入成功。这是因为 set 容器中不允许存在重复的元素,如果要插入一个容器中已存在的元素,则插入操作会失败,而 pair 中的bool 值标志插入是否成功。multiset 容器则不存在这样的情况,因此 multiset 容器返回的是一个 iterator。
2) 第二种形式的 insert() 函数将元素 elem 插入指定位置 pos,返回指向pos位置的迭代器。
3) 第三种形式的 insert() 函数将 [begin,end)区间的元素插入容器,函数没有返回值。
set 与 multiset 容器提供的 erase() 函数主要有三种重载形式,分别如下所示:
【示例1】下面通过案例演示 set 与 multiset 容器的使用,C++ 代码如下:
当需要将两个元素组合在一起时,可以选择构造 pair 对象。当一个函数需要返回两个数据时,可以返回一个 pair 对象。例如,set 容器的 insert() 函数第一种重载形式,就返回一个 pair 对象。
下面讲解一下 pair 对象的创建与使用。
make_pair() 是一个函数模板,原型如下所示:
使用 pair 构造函数和 make_pair() 函数创建 pair 对象,示例代码如下所示:
下面讲解 set 和 multiset 的常用方法。
创建set与multiset容器
set 与 multiset 都重载了多个构造函数,因此创建 set 和 multiset 容器的方式有多种。set 容器的创建方式主要有以下五种:set<T> s; //创建一个空的 set 容器,默认升序排列 set<T,op> s; //创建一个空的 set 容器,按op规则排序 set<T> s(begin,end); //创建一个容器,用 [begin,end) 区间为其初始化 set<T,op> s(begin,end); //创建一个容器,用 [begin,end) 区间为其初始化,并按 op 规则排序 set<T> s(s1); //创建一个空的 set 容器,用另一个容器 s1 初始化
下面分别用这五种方式创建 set 容器,示例代码如下所示:
set<char> s1; set<int,greater<int>()> s2; set<float> s3(begin,end); set<string,greater<string>()> s4(begin,end); set<int> s5(s2);上述代码分别用不同的方式定义了 char、int 等类型的 set 容器,其中容器 s2 与 s4 中的 greater<T> 是排序规则,指定容器中的元素按照从大到小的顺序排列。如果没有指定排序规则,则默认规则是 less<T>,即容器中元素按照从小到大的顺序排列。
greater<T>、less<T> 是 STL 中定义的函数对象,包含在 functional 头文件中。
multiset 容器的创建方式与 set 容器相同,示例代码如下所示:
multiset<char> ms1; multiset<int,greater<int>()> ms2; multiset<float> ms3(begin,end); multiset<string,greater<string>()> ms4(begin,end); multiset<int> ms5(s2);
容器的大小
与其他容器一样,set 与 multiset 容器也提供了获取容器实际元素个数的函数 size()、判断容器是否为空的函数 empty(),以及返回容器容量的成员函数 max_size(),这些函数的调用形式如下所示:s.size(); //返回容器中实际元素个数 s.empty(); //判断容器是否为空 s.max_size(); //返回容器容量上述函数调用中的 s 指集合容器,如无特殊说明,s 既可以是 set 容器也可以是 multiset 容器,即两个容器都提供了这样的函数。
容器元素的查找和统计
set 与 multiset 容器还提供了查找函数 find() 和统计函数 count(),这两种函数的调用形式如下所示:s.find(elem); s.count(elem);对上述两种函数的调用形式说明:
- find() 函数的功能是在容器中查找 elem 元素是否存在,如果元素存在,返回指向查找元素的迭代器;如果元素不存在,返回末尾迭代器。
- count() 函数用于统计 elem 元素的个数。对于 set 容器,count() 函数的返回值只能是 0 或 1;对于 multiset 容器,count() 函数返回值可能大于 1。
容器的迭代器
set 与 multiset 容器支持迭代器操作,提供了 iterator、const_iterator、reverse_iterator 和 const_reverse_iterator 四种迭代器,并且提供了获取这四种迭代器的成员函数。set 与 multiset 的迭代用法与 vector 迭代器相同。
插入和删除元素
set 与 multiset 容器提供了 insert() 函数与 erase()函数,用于向容器中插入和删除元素。insert() 函数主要有三种重载形式,分别如下所示:
s.insert(elem); //在容器中插入元素elem s.insert(pos,elem); //在pos位置插入元素elem s.insert(begin,end); //在容器中插入[begin,end)区间的元素上述三种重载形式说明:
1) 第一种形式的 insert() 函数将元素 elem 插入容器中。对于 set 容器,第一种形式的 insert() 函数调用的返回值是一个 pair<iterator,bool>对象。pair<iterator,bool> 对象的第一个参数 iterator 是迭代器,指示元素插入的位置;
第二个参数 bool 类型的值代表元素是否插入成功。这是因为 set 容器中不允许存在重复的元素,如果要插入一个容器中已存在的元素,则插入操作会失败,而 pair 中的bool 值标志插入是否成功。multiset 容器则不存在这样的情况,因此 multiset 容器返回的是一个 iterator。
2) 第二种形式的 insert() 函数将元素 elem 插入指定位置 pos,返回指向pos位置的迭代器。
3) 第三种形式的 insert() 函数将 [begin,end)区间的元素插入容器,函数没有返回值。
set 与 multiset 容器提供的 erase() 函数主要有三种重载形式,分别如下所示:
s.erase(pos); //删除pos位置上的元素 s.erase(begin,end); //删除[begin, end)区间的元素 s.erase(elem); //删除元素elem
【示例1】下面通过案例演示 set 与 multiset 容器的使用,C++ 代码如下:
#include<iostream> #include<set> #include<functional> using namespace std; int main() { set<int,greater<int>> s; //创建set容器s,元素按降序排列 multiset<char> ms; //创建multiset容器ms //向s中插入元素 pair<set<int>::iterator,bool> ps; ps = s.insert(12); if(ps.second == true) cout << "insert success" << endl; s.insert(39); s.insert(32); s.insert(26); //向ms中插入元素 ms.insert('a'); ms.insert('z'); ms.insert('T'); ms.insert('u'); ms.insert('u'); //输出两个容器中的元素 set<int>::iterator its; //创建容器s的迭代器,用于获取元素 cout << "s容器中元素:"; for(its = s.begin(); its != s.end(); its++) cout << *its << " "; cout << endl; multiset<char>::iterator itms; //创建容器ms的迭代器 cout << "ms容器中元素:"; for(itms = ms.begin(); itms != ms.end(); itms++) cout << *itms << " "; cout << endl; //查找容器ms中元素u的个数 cout <<"ms容器中u元素个数:"<< ms.count('u') << endl; return 0; }运行结果:
insert success
s容器中元素:39 32 26 12
ms容器中元素:T a u u z
ms容器中u元素个数:2
- 第 7~8 行代码分别创建了 set 容器 s 和 multiset 容器 ms,其中,容器 s 存储 int 类型数据,元素按照由大到小的顺序排列;容器 ms 存储 char类型的数据;
- 第 10~13 行代码创建一个 pair 对象,并调用insert()函数将 pair 对象表示的元素插入容器 s 中;
- 第 14~16 行代码调用 insert() 函数向容器 s 中插入其他元素;
- 第 18~22 行代码调用 insert() 函数向容器 ms 中插入元素;
- 第 24~32 行代码定义容器 s 和容器 ms 的iterator迭代器,使用迭代器遍历容器中的元素并输出;
- 第 35 行代码通过容器 ms 调用 count() 函数,查找容器 ms 中元素 u 的个数。
多学一招:pair类模板
在头文件 utility 中,定义了一个类模板 pair。pair 类模板的定义如下所示:template<class T1, class T2> struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair():first(T1()), second(T2()) {} pair(const T1& a, const T2& b):first(a), second(b) {} #ifdef __STL_MEMBER_TEMPLATES // 允许使用兼容的pair进行复制构造 template<class U1, class U2> pair(const pair<U1, U2>& p):first(p.first), second(p.second) {} #endif };pair 的主要作用是将两个数据进行组合,用来表示一个二元组或一个元素对,两个数据可以是同一个类型,也可以是不同的类型。
当需要将两个元素组合在一起时,可以选择构造 pair 对象。当一个函数需要返回两个数据时,可以返回一个 pair 对象。例如,set 容器的 insert() 函数第一种重载形式,就返回一个 pair 对象。
下面讲解一下 pair 对象的创建与使用。
1) 创建pair对象
创建 pair 对象可以调用 pair 的构造函数,还可以调用 STL 提供的 make_pair() 函数。make_pair() 是一个函数模板,原型如下所示:
template<class T1,class T2> pair<V1,V2> make_pair(T1&& t, T2&& u);在上述函数模板原型中,参数 t 与 u 是构成 pair 对象的两个数据。make_pair() 函数内部调用的仍然是 pair 构造函数。
使用 pair 构造函数和 make_pair() 函数创建 pair 对象,示例代码如下所示:
pair<int,string> p1(1, "abc"); make_pair(1, "abc");
2) pair对象的使用
pair 类模板提供了两个成员变量 first 与 second,first 表示 pair 对象中的第一个元素,second 表示第二个元素。例如下面的代码:pair<int,string> p1(1, "abc"); cout << p1.first << endl; cout << p1.second << endl;上述代码创建了一个 pair 对象 p1,p1.first 获取的是第一个元素,即 int 类型的 1;p1.second 获取的是第二个元素,即 string 类型的 "abc"。