[C++ STL] set使用详解

Posted linuxandmcu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C++ STL] set使用详解相关的知识,希望对你有一定的参考价值。

一、set介绍:

set容器内的元素会被自动排序,set与map不同,set中的元素即是键值又是实值,set不允许两个元素有相同的键值。不能通过set的迭代器去修改set元素,原因是修改元素会破坏set组织。当对容器中的元素进行插入或者删除时,操作之前的所有迭代器在操作之后依然有效。


二、用法

1、头文件

#include <set>
//set属于std命名域的,因此需要通过命名限定,例如using std::set;

2、定义及初始化

set<int> a; //定义一个int类型的集合a
//set<int> a(10); //error,未定义这种构造函数
//set<int> a(10, 1); //error,未定义这种构造函数
set<int> b(a); //定义并用集合a初始化集合b
set<int> b(a.begin(), a.end()); //将集合a中的所有元素作为集合b的初始值

除此之外,还可以直接使用数组来初始化向量:

int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5);              //将数组n的前5个元素作为集合a的初值

3、基本操作

(1) 容量函数

  • 容器大小: st.size();
  • 容器最大容量: st.max_size();
  • 更改容器大小: st.resize();
  • 容器判空: st.empty();
  • 查找键key的元素个数: st.count(key);
#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> st;
    for (int i = 0; i<6; i++)
    {
        st.insert(i);
    }

    cout << "元素大小: " << st.size() << endl;
    cout << "元素最大容量: " << st.max_size() << endl;
    cout << "键2的元素个数: " << st.count(2) << endl;
    if (st.empty())
        cout << "元素为空" << endl;

    return 0;
}

/*
元素大小: 6
元素最大容量: 214748364
键2的元素个数: 1
*/

?

(2) 增加函数

  • 在容器中插入元素:st.insert(const T& x);
  • 任意位置插入一个元素: st.insert(iterator it, const T& x);
#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> st;

    //在容器中插入元素
    st.insert(4);
    //任意位置插入一个元素
    set<int>::iterator it = st.begin();
    st.insert(it, 2);

    //display st
    cout << "st: ";
    for (it = st.begin(); it != st.end(); it++)
        cout << *it << " ";
    cout << endl;

    return 0;
}

/*
st: 2 4
*/

?

(3) 删除函数

  • 删除容器中值为elem的元素: st.pop_back(const T& elem);
  • 删除it迭代器所指的元素: st.erase(iterator it);
  • 删除区间[first,last]之间的所有元素: st.erase(iterator first, iterator last);
  • 清空所有元素: st.clear();
#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> st;
    for (int i = 0; i < 8; i++)
        st.insert(i);

    //删除容器中值为elem的元素
    st.erase(4);
    //任意位置删除一个元素
    set<int>::iterator it = st.begin();
    st.erase(it);
    //删除[first,last]之间的元素
    st.erase(st.begin(), ++st.begin());

    //display st
    cout << "st: ";
    for (it = st.begin(); it != st.end(); it++)
        cout << *it << " ";
    cout << endl;

    //清空所有元素
    st.clear();

    //clear, display st
    cout << "clear,st: ";
    for (it = st.begin(); it != st.end(); it++)
        cout << *it << " ";
    cout << endl;

    return 0;
}

/*
st: 2 3 5 6 7
clear,st:
*/

?

(4) 迭代器

  • 开始迭代器指针:st.begin();
  • 末尾迭代器指针:st.end(); //指向最后一个元素的下一个位置
  • 指向常量的开始迭代器指针: st.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
  • 指向常量的末尾迭代器指针: st.cend();
  • 反向迭代器指针,指向最后一个元素: st.rbegin();
  • 反向迭代器指针,指向第一个元素的前一个元素: st.rend();
  • 返回最后一个key<=keyElem元素的迭代器: st.lower_bound(keyElem);
  • 返回第一个key>keyElem元素的迭代器: st.upper_bound(keyElem);
  • 返回容器中key与keyElem相等的上下限的两个迭代器,这两个迭代器被放在对组(pair)中: st.equal_range(keyElem);
#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> st;
    st.insert(1);
    st.insert(2);
    st.insert(3);

    cout << "*(st.begin()): " << *(st.begin()) << endl;
    cout << "*(st.end()): " << *(--st.end()) << endl;
    cout << "*(st.cbegin()): " << *(st.cbegin()) << endl;
    cout << "*(st.cend()): " << *(--st.cend()) << endl;
    cout << "*(st.rbegin()): " << *(st.rbegin()) << endl;
    cout << "*(st.rend()): " << *(--st.rend()) << endl;
    cout << "*(st.lower_bound(2)): " << *(st.lower_bound(2)) << endl;
    cout << "*(st.upper_bound(2)): " << *(st.upper_bound(2)) << endl;
    pair<set<int>::iterator, set<int>::iterator> t_pair = st.equal_range(2);
    cout << "*(t_pair.first): " << *(t_pair.first) << endl;
    cout << "*(t_pair.second): " << *(t_pair.second) << endl;
    cout << endl;

    return 0;
}

/*
*(st.begin()): 1
*(st.end()): 3
*(st.cbegin()): 1
*(st.cend()): 3
*(st.rbegin()): 3
*(st.rend()): 1
*(st.lower_bound(2)): 2
*(st.upper_bound(2)): 3
*(t_pair.first): 2
*(t_pair.second): 3
*/

?

(5) 访问函数

  • 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(): st.find(key);
#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> st;
    for (int i = 0; i < 6; i++)
        st.insert(i);

    //通过find(key)查找键值
    set<int>::iterator it;
    it = st.find(2);
    cout << "find(key)查找到键值: " << *it << endl;

    return 0;
}

/*
find(key)查找到键值: 2
*/

?

(6) 其他函数

  • 交换两个同类型容器的元素: swap(set&, set&); 或 lst.swap(set&);
#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<int> st1;
    st1.insert(1);
    st1.insert(2);
    st1.insert(3);
    set<int> st2;
    st2.insert(4);
    st2.insert(5);
    st2.insert(6);
    //交换两个容器的元素
    //swap(st1, st2); //ok
    st1.swap(st2);

    //display st1
    cout << "交换后的st1: ";
    set<int>::iterator it;
    for (it = st1.begin(); it != st1.end(); it++)
        cout << *it << " ";
    cout << endl;
    //display st2
    cout << "交换后的st2: ";
    for (it = st2.begin(); it != st2.end(); it++)
        cout << *it << " ";
    cout << endl;

    return 0;
}

/*
交换后的st1: 4 5 6
交换后的st2: 1 2 3
*/

?

(7) 算法

  • 遍历元素
set<int>::iterator it;
for (it = st.begin(); it != st.end(); it++)
    cout << *it << endl;


三、总结

可以看到,set 与序列式容器的用法有以下几处不同:

  • set 只支持默认构造函数和拷贝构造函数,没有其它重载的构造函数。
  • set 只能使用insert的两种重载函数插入,不支持push_back()和push_front()函数。
  • set 能不通过迭代器,只通过元素值来删除该元素。
  • set 容器不提供下标操作符。为了通过键从 set 中获取元素,可使用 find 运算。
  • set 不支持STL里的reverse和sort算法。

以上是关于[C++ STL] set使用详解的主要内容,如果未能解决你的问题,请参考以下文章

[C++ STL] set使用详解

C++ STL set详解

[C++ STL] map使用详解

详解 C++ STL 六大组件,看完不懂打我...

详解 C++ STL 六大组件,看完不懂打我...

C++ STL set和multiset的使用