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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.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:clionqifeicmake-build-debugqifei.exe
8
1 2 36 4 5 1 2 10
10 5 1 36 2 4 // (顺序依赖于 hash function)
Process finished with exit code 0