C++STL中set的使用策略(一)
阿新 • • 發佈:2020-12-01
set 是 STL 中一種標準關聯容器。它底層使用平衡的搜尋樹——紅黑樹實現,插入刪除操作時僅僅需要指標操作節點即可完成,不涉及到記憶體移動和拷貝,所以效率比較高。
set,顧名思義是 “集合” 的意思,在 set 中元素都是唯一的,而且預設情況下會對元素自動進行升序排列,支援集合的交 (set_intersection), 差 (set_difference) 並 (set_union),對稱差 (set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允許重複那麼可以使用 multiset。
- 標頭檔案:
<set>
- 定義:
set<int> q
- 輸入(插入):
insert(x)
- 刪除指定元素:
erase(x)
- 清空:
clear()
- 判空:
empty()
- 大小:
size()
- 二分查詢:
q.lower_bound(x)
- 有序輸出
set<int>::iterator it;
for(it = q.begin();it != q.end();it++)
{
cout<<*it<<endl;
}
set 模板原型
template <class Key, class Compare=less<Key>, class Alloc=STL_DEFAULT_ALLOCATOR(Key) > //Key為元素(鍵值)型別 greater是從升序排序(預設),可以改為less(降序排序)
set 容器的建立
#include <iostream> #include <set> #include <functional> using namespace std; set<int> s; int main() { set<int,greater<int> > seta; //greater<int>可以不寫,預設是升序 set<int, less<int> > setb; //建立一個降序的set,需包含標頭檔案functional int a[5] = {1,2,3,4,5}; set<int > setc(a,a+5); //陣列a初始化一個set; set<int > setd(setc.begin(),setc.end()); //setc初始化一個set //上述兩例均為區間初始化 set<int > sete(setd); //拷貝構造建立set return 0; } //注意寫法set<int,less<int> >或set<int,greater<int> >,如果不空格,“>>”被當作位運算可能報錯
set 容器的增刪改查
1.插入
#include <iostream>
#include <set>
using namespace std;
set<int >s;
void setprint(int cnt)
{
cout << "Test output :" << cnt << ":" << endl;
for(set<int>::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
puts("");
return ;
}
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;
}
2.刪除
//s.erase(); 刪除一個元素
//s.clear(); 刪除set容器中的所有的元素
#include <iostream>
#include <set>
using namespace std;
set<int >s;
void setprint(int cnt)
{
cout << "Test output :" << cnt << ":" << endl;
for(set<int>::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
puts("");
return ;
}
int main()
{
int cnt = 1;
for(int i = 1; i < 11; i++){
s.insert(i);
}
setprint(cnt++);
s.erase(9); //根據元素刪除
setprint(cnt++);
set<int>::iterator ita = s.begin();
set<int>::iterator itb = s.begin();
s.erase(ita); //刪除迭代器指向位置的元素
setprint(cnt++);
ita = s.begin();
itb = s.begin();
itb++;itb++;
s.erase(ita,itb); //刪除區間[ita,itb)的元素
setprint(cnt);
s.clear();
return 0;
}
3.修改
不能直接修改容器內資料,所以只能刪除某元素再插入要修改的數值。
4.查詢
//s.find() 查詢一個元素,如果容器中不存在該元素,返回值等於s.end()
#include <iostream>
#include <set>
using namespace std;
set<int >s;
void setprint(int cnt){
cout << "Test output :" << cnt << ":" << endl;
for(set<int>::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
puts("");
return ;
}
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;
if(s.find(3) == s.end())
cout << "3 is non-existent" << endl;
else
cout << "2 is existent" << endl;
return 0;
}
set 的其他常用操作
s.lower_bound()
返回第一個大於或等於給定關鍵值的元素
s.upper_bound()
返回第一個大於給定關鍵值的元素
s.equal_range()
返回一對定位器,分別表示 第一個大於或等於給定關鍵值的元素 和 第一個大於給定關鍵值的元素,這個返回值是一個pair型別,如果這一對定位器中哪個返回失敗,就會等於s.end()
#include <iostream>
#include <set>
using namespace std;
int main(){
set<int> 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中 & 判斷set是否為空
#include <iostream>
#include <set>
#include <functional>
using namespace std;
int main(){
set<int > s;
if(s.empty()) cout << "容器為空" << endl;
s.insert(1);
if(!s.empty()) cout << "容器不為空" << endl;
if(s.count(1)) cout << "1在容器中" << endl;
if(!s.count(2)) cout << "2不在容器中" << endl;
return 0;
}
//自定義比較函式
#include <iostream>
#include <set>
#include <functional>
using namespace std;
struct cmp{
bool operator () (const int &a, const int &b){
return a > b;
}
};
set<int, cmp>s; //自定義排序函式構造set
void setprint(int cnt){
cout << "Test output :" << cnt << ":" << endl;
for(set<int,cmp>::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;
}