C++中STL标准容器类 SET 简单入门使用详解,SET容器类简单相关实例

C++标准容器类STL中的集合 set 比较特殊,在其中存储的元素是独一无二的,因为它存储的元素值同时也充当“key”的角色,也即可以通过“key”访问指定的元素。此外,元素一旦被插入到 set 容器类中,就不能在被修改,不过,我们可以删除它或者插入新的元素。

STL 中的集合 set

要使用C++标准容器类 STL 中的 set,需要先包含<set>头文件:

#include <set>

之后,便可定义 set 对象:

set<data_type> myset;

其中的 data_type 可以是任意的数据类型,所谓“任意”,当然也包括 set 本身,例如下面这两行C++代码:

set<int> int_set;
set<set<int> > int_sets;

上述第一行代码定义的 int 类型的 set 容器,其中可以存储 int 型的元素。第二行代码则定义了 set 类型的元素,其中可以存储 set 型的元素。

操作 set

操作C++中标准容器类 set 很像操作 map(本专栏之后会讨论),下面是 set 类的一些基本操作(成员函数):

  • begin:返回指向 set 第一个元素的迭代器。
  • end:返回指向 set 最后一个元素的迭代器。
  • insert:将新元素插入 set,insert 方法一般有 3 中形式:
    • insert(elem):将 elem 直接插入到 set 中,并且重新排序。
    • insert(pos, elem):将 elem 插入到 set 中的 pos 位置。
    • insert(it.begin(), it.end()):将 it 表示范围内的元素插入到 set。
  • erase:从 set 中删除一个元素。
  • size:返回 set 中元素的数目。
  • max_size:返回 set 能够容纳的最大 size。
  • empty:返回 set 中是否有元素。
  • clear:删除 set 中的所有元素。
  • find:在 set 中查找元素,如果找到了,返回一个指向改元素的迭代器,如果找不到,返回一个指向 set.end 的迭代器。

作为实例,下面这段C++代码简单使用了上述各种方法,请看:

#include <iostream>
#include <set>
#include <iterator>
using namespace std;

int main()
{
    set <int> myset;

    myset.insert(140);
    myset.insert(130);
    myset.insert(160);
    myset.insert(120);

    cout<<"\nSize of myset: "<<myset.size();

    set <int > :: iterator itr;
    cout << "\nThe set myset is : ";
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 
    cout << endl;

    set<int>::iterator it = myset.begin();
    myset.insert(it,100);

    cout << "\nAfter inserting 100,the set myset is : ";
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 
    cout << endl;

    int arr[3] = {110,150,150};

    myset.insert(arr,arr+2);
    cout << "\nAfter inserting array arr,the set myset is : ";
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 
    cout << endl;

    cout << "\nAfter removal of elements less than 130, myset: ";

    myset.erase(myset.begin(), myset.find(130));
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 

    cout << endl;

    return 0;
}

编译并执行这段C++代码,得到如下输出:

Size of myset: 4
The set myset is :  120 130 140 160

After inserting 100,the set myset is :  100 120 130 140 160

After inserting array arr,the set myset is :  100 110 120 130 140 150 160

After removal of elements less than 130, myset:  130 140 150 160

这段C++程序一开始通过简单的 insert() 函数创建了一个 size 为 4 的 set。

接着,程序使用了另外一种形式的 insert(it,100) 函数将 100 插入到 set 中,从输出来看,元素 100 被成功插入到 set 中了,而且 set 也被重新排序了。

然后,我们又通过第三种形式的 insert(arr,arr+2) 函数插入了数组 {110,150,150}。但是从输出来看,在执行完插入后,set 中只有一个 150,这是因为 set 中的元素是独一无二的。

最后,我们通过 find() 函数查找到元素 130 在 set 中的位置,并且调用 erase() 函数将 set 开头到该位置的元素删除,也就是将小于 130 的元素删除,从结果来看,一切与预期一致。

“多元 set” multiset

从字面意思来看,multiset 可以拆分成 multi 和 set,因此 multiset 的本质是 set,而 multi 则说明了它与普通 set 不同的地方:multiset 允许内部有相同的元素

定义一个 multiset 是简单的,例如定义一个存放 int 元素的 multiset:

multiset<int> mset;

操作 multiset 的方式与普通 set 没有什么不同,下面这段C++代码是一个实例,请看:

#include <iostream>
#include <set>
#include <iterator>
using namespace std;

int main()
{
    multiset <int> myset;

    myset.insert(11);
    myset.insert(13);
    myset.insert(13);
    myset.insert(10);

    cout<<"\nSize of myset: "<<myset.size();

    set <int > :: iterator itr;
    cout << "\nAfter inserting four elements, the multiset myset is : ";
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 
    cout << endl;

    set<int>::iterator it = myset.begin();
    myset.insert(it,15);

    cout << "\nAfter inserting 15,the multiset myset is : ";
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 
    cout << endl;

    cout << "\nAfter removal of elements less than 15, myset: ";

    myset.erase(myset.begin(), myset.find(15));
    for (itr = myset.begin(); itr != myset.end(); ++itr)
        cout << ' ' << *itr; 

    cout << endl;

    return 0;
}

编译并执行这段C++代码,可得到如下输出:

Size of myset: 4
After inserting four elements, the multiset myset is :  10 11 13 13

After inserting 15,the multiset myset is :  10 11 13 13 15

After removal of elements less than 15, myset:  15

代码一开始插入了 4 个元素到 multiset,其中有两个元素是相同的。但是从最后的输出来看,multiset 不像普通 set,它允许内部存放两个相同的元素。其他过程就与 set 的实例没什么不同了。

“无序 set” unreordered_set

前面讨论了两种集合:set 和 multiset。其中,set 是一个有序的集合,并且其中的元素独一无二,也即不会有两个相同的元素。multiset 也是一个“有序”的集合,它与 set 的不同点在于其内部可以存放相同的元素。

C++中的 unreordered_set 是一个“无序”的集合容器,其中存放的元素的顺序是任意的,这一点与 set/multiset 是不同的。

类似于 map 容器类,unreordered_set 也使用了哈希表,通过 key 访问元素。作为对比,set 在其内部使用了平衡树管理元素。

使用“无序 set”,需要先包含头文件<reordered_set>,相关C++代码如下:

#include <unordered_set>

定义一个“无序 set” 是简单的,例如定义一个存放 int 元素的对象的 C++代码可以如下写:

unordered_set<int> uset;

操作 unreordered_set 的方法大都与 set 相同,下面是一段简单的C++代码实例,请看:

#include<iostream>
#include <unordered_set>
using namespace std;

int main()
{
    unordered_set<int> uset; 
    unordered_set<int> :: iterator it; 

    for(int i=0;i<5;i++){
        uset.insert(i+2); 
    }

    cout<<"\nSize of uset: "<<uset.size();
    cout<<endl;

    it= uset.begin();
    uset.insert(it,99);

    int ary[]= { 13, 26, 39};
    uset.insert(ary, ary+3); // Inserting using method3

    cout<<"\nElements in unordered set are: ";
    for(it= uset.begin(); it!=uset.end(); it++) cout << *it << " ";  
    cout<<endl;

    int key=13;
    if (uset.find(key) == uset.end()) 
                cout<<"\nkey = "<< key << "not found\n\n"; 
        else
                cout << "\nFound key = " << key << endl << endl;

    cout<<"umap bucket_count : "<<uset.bucket_count();
               cout<<"\nbucket_size : "<<uset.bucket_size(2);

    return 0;
}

编译并执行这段C++代码,得到如下输出:

Size of uset: 5

Elements in unordered set are: 99 39 6 5 26 4 3 13 2 

Found key = 13

umap bucket_count : 11

代码开头插入 5 个元素然后插入 4 个元素到无序 set 的操作与之前没什么不同,但是从之后的输出来看,unreordered_set 中存放的元素顺序与插入顺序并不对应,这对于内部使用哈希表管理元素的无序 set 来说并无不妥。

接着,程序调用了 find() 函数查找 key=13 是否在无序 set 中,从输出来看,程序找到了对应的结果。

最后,程序调用了之前两种 set 没有的两个函数:bucket_count() 和 bucket_size() 函数,这两个函数和 unreordered_set 内部使用的哈希映射有关。

小结

本文主要讨论了C++标准容器类中的三种 set,它们各有特点:set 不允许自己内部有两个相同的元素,而 multiset 则可以,不过这两种序列中的所有元素都是有序的,与之对应的,unreordered_set 中的元素是无序的,其内部元素的顺序与插入顺序没有关系。

阅读更多:   C++
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif