STL之set常用函数详解

STL之set常用函数详解

1.关于set

C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入、排序、删除、查找等。让用户在STL使用过程中,并不会感到陌生。

关于set,必须说明的是set关联式容器。set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。

  • 内部自动有序
  • 不含重复元素的容器

2.set的定义 必须引入头文件 #include <set>

  • 定义单个集合
set<typename> name;
  • set数组的定义和vector相同
set<typename> Arrayname[100]  //  这里定义了一百个set容器,下标为0~99;

3.set元素的访问

  • set中的元素只能通过迭代器访问
set<typename>::iterator it;

这样就得到了迭代器it,并且可以通过*it来访问set里面的元素。

除开vector和string之外的STL都不支持*(it+i)的访问方式

#include <iostream>
#include <set>
#include <string>
using namespace std;
int main() {
    set<int> a;
    int n;
    cin>>n;  //  n代表要输入的数
    while(n--)  
    {
        int tmp;
        cin>>tmp;
        a.insert(tmp);
    }
    for(auto it=a.begin();it!=a.end();it++)
        cout<<*it<<" ";
    return 0;
}

//  输出结果:
G:\clion\qifei\cmake-build-debug\qifei.exe
6
6
5
4
7
5
4
4 5 6 7
Process finished with exit code 0

4.set常用函数的实例解析

  • insert(x),可以将元素x插入set容器中。
  • find(x),返回X所对应值的迭代器。
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main() {
    set<int> a;
    int n;
    cin>>n;  //  n代表要输入的数
    while(n--)
    {
        int tmp;
        cin>>tmp;
        a.insert(tmp);
    }
    set<int>::iterator it=a.find(5);
    cout<<*it<<endl;
    return 0;
}
//  输出结果:
G:\clion\qifei\cmake-build-debug\qifei.exe
3
1
2
5
5

Process finished with exit code 0

  • erase()

    • 删除单个元素

    • a.erase(it),it为要删除的元素的迭代器

    • #include <iostream>
      #include <set>
      #include <string>
      using namespace std;
      int main() {
          set<int> a;
          int n;
          cin>>n;  //  n代表要输入的数
          while(n--)
          {
              int tmp;
              cin>>tmp;
              a.insert(tmp);
          }
          set<int>::iterator it=a.find(5);
          a.erase(it);
          for(it=a.begin();it!=a.end();it++)
              cout<<*it<<" ";
          return 0;
      }
      //  输出结果:
      G:\clion\qifei\cmake-build-debug\qifei.exe
      5
      4 5 1 2 3
      1 2 3 4
      Process finished with exit code 0
      
      
    • a.erase(value),value为要删除的元素的值。

    • #include <iostream>
      #include <set>
      #include <string>
      using namespace std;
      int main() {
          set<int> a;
          int n;
          cin>>n;  //  n代表要输入的数
          while(n--)
          {
              int tmp;
              cin>>tmp;
              a.insert(tmp);
          }
          set<int>::iterator it;
          a.erase(8);
          for(it=a.begin();it!=a.end();it++)
              cout<<*it<<" ";
          return 0;
      }
      //  输出结果:
      G:\clion\qifei\cmake-build-debug\qifei.exe
      4
      8 5 3 9
      3 5 9
      Process finished with exit code 0
      
      
    • a.erase(first,last),first为对应要删除区间的开始的迭代器,last为要删除区间的尾迭代器的下一个地址。

    • #include <iostream>
      #include <set>
      #include <string>
      using namespace std;
      int main() {
          set<int> a;
          int n;
          cin>>n;  //  n代表要输入的数
          while(n--)
          {
              int tmp;
              cin>>tmp;
              a.insert(tmp);
          }
          set<int>::iterator it=a.find(8);
          set<int>::iterator ptr=a.find(3);
          a.erase(ptr,it);
          for(it=a.begin();it!=a.end();it++)
              cout<<*it<<" ";
          return 0;
      }
      //  输出结果:
      G:\clion\qifei\cmake-build-debug\qifei.exe
      8
      1 2 4 3 8 5 6 10
      1 2 8 10
      Process finished with exit code 0
      
      
  • size()用来获得set的元素个数。

#include <iostream>
#include <set>
#include <string>
using namespace std;
int main() {
    set<int> a;
    int n;
    cin>>n;  //  n代表要输入的数
    while(n--)
    {
        int tmp;
        cin>>tmp;
        a.insert(tmp);
    }
    cout<<a.size()<<endl;
    return 0;
}
//   输出结果:
G:\clion\qifei\cmake-build-debug\qifei.exe
10
1 2 3 4 5 66 7 8 9 3
9

Process finished with exit code 0

  • clear(),清空set所有的元素。
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main() {
    set<int> a;
    int n;
    cin>>n;  //  n代表要输入的数
    while(n--)
    {
        int tmp;
        cin>>tmp;
        a.insert(tmp);
    }
    a.clear();
    cout<<a.size()<<endl;
    return 0;
}
//  输出结果:
G:\clion\qifei\cmake-build-debug\qifei.exe
10
4 5 6 12 3 789 1 2 3 4
0

Process finished with exit code 0

c++ set与unordered_set区别

  • c++ std中set与unordered_set区别和map与unordered_map区别类似:

  • set基于红黑树实现,红黑树具有自动排序的功能,因此map内部所有的数据,在任何时候,都是有序的。unordered_set基于哈希表,数据插入和查找的时间复杂度很低,几乎是常数时间,而代价是消耗比较多的内存,无自动排序功能。底层实现上,使用一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域进行保存。

#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;
int main() {
    unordered_set<int> a;
    int n;
    cin>>n;  //  n代表要输入的数
    while(n--)
    {
        int tmp;
        cin>>tmp;
        a.insert(tmp);
    }
    for(auto it=a.begin();it!=a.end();it++)
        cout<<*it<<" ";
    return 0;
}

//  输出结果:
G:\clion\qifei\cmake-build-debug\qifei.exe
8
1 2 36 4 5 1 2 10
10 5 1 36 2 4    //  (顺序依赖于 hash function)
Process finished with exit code 0

posted @ 2020-04-08 15:19  Yqifei  阅读(559)  评论(0编辑  收藏  举报