STL:set用法总结

一、Set介绍

除了没有单独的键,set 容器和 map 容器很相似。

定义 set 容器的模板如下四种:

  • set 容器保存 T 类型的对象,而且保存的对象是唯一的。其中保存的元素是有序的,默认用 less 对象比较。可以用相等、不相等来判断对象是否相同。有序,底层红黑树
  • multiSet 容器和 set 容器保存 T 类型对象的方式相同,但它可以保存重复的对象。有序,底层红黑树
  • unorderd_set 容器保存 T 类型的对象,而且对象是唯一的。元素在容器中的位置由元素的哈希值决定。默认用 equal_to 对象来判断元素是否相等,无序的,底层哈希表。
  • unordered_multiset 容器保存 T 类型对象的方式和 unorderd_set 相同,但可以保存重复的对象。无序,底层哈希表。

定义 set 的模板有 4 种,其中两种默认使用 less 来对元素排序,另外两种使用哈希值来保存元素。有序 set 的模板定义在 set 头文件中。无序 set 的模板定义在 unordered_set 头文件中。因此有序 set 包含的元素必须支持比较运算,无序 set 中的元素必须支持哈希运算。

从有序和无序关联容器获取的各种迭代器之间有一些区别。我们可以从有序容器得到正向和反向迭代器,但是只能从无序容器得到正向迭代器。
一般来说,当 set 中有大量元素时,在无序 set 上执行的随机插入和检索操作要比有序 set 快。在有 n 个元素的有序 set 中检索元素的时间复杂度是 logn。在无序 set 中检索元素的平均时间复杂度是常量O(1),这和元素的个数无关,尽管实际性能会受元素哈希操作和内部组织效率的影响。

二、Set常用函数

s.begin()      返回set容器的第一个元素
s.end()      返回set容器的最后一个元素
s.clear()       删除set容器中的所有的元素
s.empty()     判断set容器是否为空
s.insert()      插入一个元素
s.erase(it)       删除一个元素
s.size()     返回当前set容器中的元素个数

equal_range():返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值. 

还有两个功能类似的函数:count()和find()
1.count() :用来查找set中某个元素出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。
2.find():   用来查找set中某个元素出现的位置。如果找到,就返回这个元素的迭代器,如果这个元素不存在,则返回 s.end() 。 (最后一个元素的下一个位置,s为set的变量名)

三、Set的创建

#include 
#include 
#include 
using namespace std;
set s;
 
int main(){
   set setA; //默认是小于比较器less的set
 
   set > setB; //创建一个带大于比较器的set,需包含头文件functional
 
   int a[5] = {1,2,3,4,5};
   set setC(a,a+5); //数组a初始化一个set;
 
   set setD(setC.begin(),setC.end()); //setc初始化一个set
   //上述两例均为区间初始化
 
   set setE(setD); //拷贝构造创建set
   return 0;
}

四、Set插入

int main(){
    int cnt = 1;
    s.insert(1);
    s.insert(2);
    s.insert(5);
    setprint(cnt++);
 
    s.insert(2); //set只允许用一个值出现一次,要插入相同元素请用multiset
    setprint(cnt++);
 
    int a[4] = {11,12,13,14};
    s.insert(a,a+4); //将区间[a, a+4]里的元素插入容器
    setprint(cnt++);
 
    return 0;
}

五、Set删除

set.erase(n)      删除元素n
set.clear()       删除set容器中的所有的元素

int main(){
    int cnt = 1;
    for(int i = 1; i < 11; i++){
        s.insert(i);
    }
 
    s.erase(9); //根据元素删除
    setprint(cnt++);
 
    set::iterator ita = s.begin();
    set::iterator itb = s.begin();
    s.erase(ita);  //删除迭代器指向位置的元素
 
    ita = s.begin();
    itb = s.begin();
    itb++;itb++;
    s.erase(ita,itb); //删除区间[ita,itb)的元素
    s.clear();
    return 0;
}

六、Set修改

不能直接修改容器内数据,所以只能删除某元素再插入要修改的数值。

所有 set 容器的成员函数返回的迭代器都指向 const T 类型的元素。因此,iterator 迭代器会指向 const 元素, reverse_iterator 和其他类型的迭代器也是如此。这意味着我们不能修改元素。如果想要修改 set 容器中的元素,必须先删除它,然后再插入修改后的版本。

七、查找

set.find() 查找一个元素,如果容器中不存在该元素,返回值等于set.end()

#include 
#include 
using namespace std;
sets;

int main(){
    int cnt = 1;
    s.insert(1);
    s.insert(2);
    s.insert(5);
    setprint(cnt++);
 
    if(s.find(2) != s.end()) 
        cout << "2 is existent" << endl;
    else 
        cout << "2 is non-existent" << endl;

    return 0;
}

八、Set遍历

for (set::iterator it = s.begin(); it != s.end(); ++it)    
{
    cout << *it << endl;
}

九、Set其它操作

s.lower_bound() 返回第一个大于或等于给定关键值的元素
s.upper_bound() 返回第一个大于给定关键值的元素
s.equal_range() 返回一对定位器,分别表示 第一个大于或等于给定关键值的元素 和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于s.end()

#include 
#include 
using namespace std;
 
int main(){
    set s;
    s.insert(1);
    s.insert(2);
    s.insert(5);
 
    cout << "lower_bound & upper_bound test:" << endl;
 
    cout << "第一个大于或等于3的元素: " << *s.lower_bound(3) << endl;
    cout << "第一个大于或等于2的元素: " <<*s.lower_bound(2) << endl;
    cout << "第一个大于2的元素: " <<*s.upper_bound(2) << endl;
 
    cout << "equal_range test:" << endl;
 
    cout << "第一个大于或等于2的元素: " <<  *s.equal_range(2).first << endl;
    cout << "第一个大于2的元素: " << *s.equal_range(2).second << endl;
    return 0;
}

十、Set中存放自定义类型(struct )

#include
#include
#include
using namespace std;
struct Info
{
    string name;
    double score;
    bool operator < (const Info &a) const // 重载“<”操作符,自定义排序规则
    {
        //按score由大到小排序。如果要由小到大排序,使用“>”即可。
        return a.score < score;
    }
};
int main()
{
    set s;
    Info info;

    //插入三个元素
    info.name = "Jack";
    info.score = 80;
    s.insert(info);
    info.name = "Tom";
    info.score = 99;
    s.insert(info);
    info.name = "Steaven";
    info.score = 60;
    s.insert(info);

    set::iterator it;
    for(it = s.begin(); it != s.end(); it++)
        cout << (*it).name << " : " << (*it).score << endl; 
    return 0;
}
/*
运行结果:
Tom : 99
Jack : 80
Steaven : 60
*/
#include 
#include 
#include 
using namespace std;
 
struct cmp{
    bool operator () (const int &a, const int &b){
        return a > b;
    }
};
sets; //自定义排序函数构造set
void setprint(int cnt){
    cout << "Test output :" << cnt << ":" << endl;
    for(set::iterator it = s.begin(); it!= s.end(); it++)
        cout << *it << " ";
    puts("");
    return ;
}
int main(){
    s.insert(1);
    s.insert(2);
    s.insert(6);
    setprint(1);
    return 0;
}
//结果
6 2 1

 

你可能感兴趣的:(STL)