STL 整理(map、set、vector、list、stack、queue、deque、priority_queue)
向量(vector) <vector>
連續儲存的元素<vector>
Vector<int>c;
c.back() 傳回最後一個數據,不檢查這個資料是否存在。
c.clear() 移除容器中所有資料。
c.empty() 判斷容器是否為空。
c.front() 傳回地一個數據。
c.pop_back() 刪除最後一個數據。
c.push_back(elem) 在尾部加入一個數據。
c[i] 等同於 c.at(i);
列表(list) <list>
由節點組成的雙向連結串列,每個結點包含著一個元素<list>
list<int> list1(1,2,3)
front()返回第一個元素的引用 int nRet =list1.front() // nRet = 1
back()返回最後一元素的引用 int nRet =list1.back() // nRet = 3
push_back()增加一元素到連結串列尾 list1.push_back(4) //list1(1,2,3,4)
push_front()增加一元素到連結串列頭 list1.push_front(4) //list1(4,1,2,3)
pop_back()刪除連結串列尾的一個元素 list1.pop_back() //list1(1,2)
pop_front()刪除連結串列頭的一元素 list1.pop_front() //list1(2,3)
clear()刪除所有元素 list1.clear(); // list1空了,list1.size()=0
sort()對連結串列排序,預設升序(可自定義回撥函式)
list物件L1(4,3,5,1,4) L1.sort();
//L1(1,3,4,4,5) L1.sort(greater<int>());
//L1(5,4,4,3,1)
insert()在指定位置插入一個或多個元素
list1.insert(++list1.begin(),9); // list1(1,9,2,3)
list1.insert(list1.begin(),2,9); // list1(9,9,1,2,3);
list1.insert(list1.begin(),list2.begin(),--list2.end());//list1(4,5,1,2,3);
swap()交換兩個連結串列(兩個過載)
list1.swap(list2); //list1(4,5,6) list2(1,2,3)
unique()刪除相鄰重複元素
L1(1,1,4,3,5,1)
L1.unique();// L1(1,4,3,5,1)
merge()合併兩個有序連結串列並使之有序
// 升序list1.merge(list2); //list1(1,2,3,4,5,6) list2現為空
// 降序L1(3,2,1), L2(6,5,4)L1.merge(L2, greater<int>()); //list1(6,5,4,3,2,1) list2現為空
reverse()反轉連結串列:list1.reverse(); //list1(3,2,1)
remove()刪除連結串列中匹配值的元素(匹配元素全部刪除)list物件L1(4,3,5,1,4)L1.remove(4); //L1(3,5,1);
empty()判斷是否連結串列為空bool bRet =L1.empty(); //若L1為空,bRet = true,否則bRet = false。
rbegin()返回連結串列最後一元素的後向指標(reverse_iteratoror const)list<int>::reverse_iterator it = list1.rbegin(); //*it = 3
rend()返回連結串列第一元素的下一位置的後向指標list<int>::reverse_iteratorit = list1.rend(); // *(--riter) = 1
集合(set) <set>
由節點組成的紅黑樹,每個節點都包含著一個元素,節點之間以某種作用於元素對的謂詞排列,沒有兩個不同的元素能夠擁有相同的次序 <set>
set<type>: 以less<>為排序法則的set
set<type,op>: 以op為排序法則的set
struct op{
bool operator()(const rec&a,const rec&b){
return a.x<b.x||a.x==b.x&&a.y<b.y;
}
};
1.1 set::begin
功能:返回第一個元素的定位器(iterator)的地址。
set <char>::iterator cp;
ctr.insert('a');
ctr.insert('b');
cp=ctr.begin(); //定位到ctr 的開始位置
1.2 set::clear
功能:將一個set 容器的全部元素刪除。
1.3 set::count
功能:返回對應某個關鍵字的元素的個數。好像都是1吧
1.4 set::empty
功能:測試一個set 容器是否為空。
1.5 set::end
功能:返回最後一個元素後面的定位器(iterator)的地址。
1.7 set::erase
功能:將一個或一定範圍的元素刪除。
1.8 set::find
功能:求出與給定的關鍵字相等的元素的定位器。
set <string> ctr;
ctr.insert("abc");
ctr.insert("abcd");
ctr.insert("abcf");
set <string>::iterator cp;
cp=ctr.find("abc"); //查詢key=1 的元素
if(cp!=ctr.end())
cout<<*cp <<endl;//顯示abc
cp=ctr.find("adf"); //查詢key=2 的元素
if(cp!=ctr.end())
cout<<*cp <<endl;//不顯示
cp=ctr.find("gfv"); //查詢key=3 的元素
if(cp!=ctr.end())
cout<<*cp <<endl;// 不顯示
1.10 set::insert
功能:將一個元素或者一定數量的元素插入到set 的特定位置中。
1.25 set::upper_bound
功能:求出指向第一個關鍵字的值是大於一個給定值的元素的定位器。
cp=ctr.upper_bound(2);//輸出比2大的最小元素
多重集合(multiset)< set>
允許存在兩個次序相等的元素的集合 <set>
multiset<type>: 以less<>為排序法則的multiset
multiset<type, op>: 以op為排序法則的multise
struct op{
bool operator()(const rec&a,const rec&b){
return a.x<b.x||a.x==b.x&&a.y<b.y;
}
};
multiset<int>h;
__typeof(h.begin()) c=h.begin();//c指向h序列中第一個元素的地址,第一個元素是最小的元素
printf("%d ",*c);//將地址c存的資料輸出
h.erase(c);//從h序列中將c指向的元素刪除
__typeof()是個好東西~
棧(stack) <stack>
後進先出的值的排列 <stack>
定義一個stack的變數stack<int> s;
入棧,如例:s.push(x);
出棧,如例:s.pop();注意,出棧操作只是刪除棧頂元素,並不返回該元素。
訪問棧頂,如例:s.top()
判斷棧空,如例:s.empty(),當棧空時,返回true。
訪問棧中的元素個數,如例:s.size()
佇列(queue) <queue>
先進先出的執的排列 <queue>
定義一個queue的變數 queue<Type> M
檢視是否為空範例 M.empty() 是的話返回1,不是返回0;
從已有元素後面增加元素M.push()
輸出現有元素的個數 M.size()
顯示第一個元素 M.front()
顯示最後一個元素 M.back()
清除第一個元素 M.pop()
優先佇列(priority_queue) <queue>
元素的次序是由作用於所儲存的值對上的某種謂詞決定的的一種佇列 <queue>
1、預設從大到小
priority_queue<int> qi;
2、從小到大輸出可以傳入一個比較函式,使用functional.h函式物件作為比較函式,great<int>(小到大) less<int>(大到小)
priority_queue<int, vector<int>, greater<int> >qi2; 第二個引數為容器型別。第三個引數為比較函式。
3、自定義:
struct cmp // 最小優先佇列
{
bool operator()(const long long i,constlong long j)
{
return i>j;
}
};
priority_queue<int,vector<longlong>,cmp> Q;
struct node // 最小優先佇列
{
int id,len;
bool operator < (const node &b)const// 只能過載小於號
{
return len>b.len;
}
};
priority_queue<node>Q;
Q.empty() // 判斷佇列是否為空返回ture表示空返回false表示空 bool
Q.top() // 返回頂端元素的值元素還在佇列裡
Q.pop() // 刪除頂端元素 void
Q.push(V) // 把long long型的數V加入到佇列裡它會制動條件V的位置void
Q.size() // 返回佇列裡元素個數 unsigned int
雙端佇列(deque) <deque>
連續儲存的指向不同元素的指標所組成的陣列<deque>
deque<int>c
c.pop_back() 刪除最後一個數據。
c.pop_front() 刪除頭部資料。
c.push_back(elem) 在尾部加入一個數據。
c.push_front(elem) 在頭部插入一個數據。
c.clear() 移除容器中所有資料。
c.front() 傳回地一個數據。
c.back() 傳回最後一個數據,不檢查這個資料是否存在。
c.size() 返回容器中實際資料的個數。
c.empty() 判斷容器是否為空。
c[i] 等同於 c.at(i);
對映(map) 由{鍵,值}對組成的集合 <map>
以某種作用於鍵對上的謂詞排列 <map>
三種插入資料的方法(第一種和第二種是一樣的,當map中有這個關鍵字時,insert操作是插入不了資料的,用陣列方式會覆蓋以前該關鍵字對應的值)
1. map<int,string>mapStudent;
mapStudent.insert(pair<int,string>(1,"student_one"));
mapStudent.insert(pair<int,string>(2,"student_two"));
2. map<int,string>mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student_one"));
mapStudent.insert(map<int,string>::value_type(2,"student_two"));
3. map<int,string>mapStudent;
mapStudent[1]="student_one";
mapStudent[2]="student_two";
可以用pair來獲得是否插入成功
map<int,string>mapStudent;
pair<map<int,string>::iterator,bool> insert_pair;
insert_pair=mapStudent.insert(pair<int,string>(1,"student_one"));
if(insert_pair.second==true)
cout<<"insert Successfully"<<endl;
怎麼知道當前已經插入了多少資料呢,可以用size函式,用法如下:int nSize=mapStudent.size();
清空map中的資料可以用clear()函式,判定map中是否有資料可以用empty()函式
要判定一個數據(關鍵字)是否在map中出現的方法比較多,這裡給出三種資料查詢方法
第一種:用count函式來判定關鍵字是否出現,其缺點是無法定位資料出現位置,由於map的特性,一對一的對映關係,就決定了count函式的返回值只有兩個,要麼是0,要麼是1,出現的情況,返回1
map<int,string> mapStudent;
mapStudent.insert(pair<int,string>(1,"student_one"));
mapStudent.insert(pair<int,string>(2,"student_two"));
mapStudent.insert(pair<int,string>(3,"student_three"));
int t1,t2;
t1=mapStudent.count(4);
t2=mapStudent.count(1);
第二種:用find函式來定位資料出現位置,它返回的一個迭代器,當資料出現時,它返回資料所在位置的迭代器
map<string,int>mapStudent;
mapStudent.insert(pair<string,int>("student_one",1));
mapStudent.insert(pair<string,int>("student_two",2));
mapStudent.insert(pair<string,int>("student_three",3));
map<string,int>::iteratoriter;
charch[]="student_three";
iter=mapStudent.find(ch);
if(iter!=mapStudent.end())
cout<<"Find,the value is: "<<iter->second<<endl;
else
cout<<"Donot Find"<<endl;
清空map中的資料可以用clear()函式,判定map中是否有資料可以用empty()函式,它返回true則說明是空
//如果要刪除,用迭代器刪除
map<int,string>::iterator iter;
iter=mapStudent.find(1);
mapStudent.erase(iter);
//如果要刪除,用關鍵字刪除
intn=mapStudent.erase(1);//如果刪除了n會返回,否則返回
//用迭代器,成片的刪除
mapStudent.erase(mapStudent.begin(),mapStudent.end());
//一下程式碼把整個map清空
mapStudent.erase(mapStudent.begin(),mapStudent.end());
排序
一、
#include <map>
#include <string>
using namespace std;
typedef struct tagStudentInfo
{
int nID;
string strName;
booloperator < (tagStudentInfo const& _A) const
{
//這個函式指定排序策略,按nID排序,如果nID相等的話,按strName排序
if(nID< _A.nID)
return true;
if(nID== _A.nID)
return strName.compare(_A.strName) < 0;
returnfalse;
}
}StudentInfo, *PStudentInfo; //學生資訊
int main()
{
//用學生資訊對映分數
map<StudentInfo, int>mapStudent;
StudentInfo studentInfo;
studentInfo.nID = 1;
studentInfo.strName ="student_one";
mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));
studentInfo.nID = 2;
studentInfo.strName ="student_two";
mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));
}
二、
#include <map>
#include <string>
#include <iostream>
using namespace std;
typedef struct tagStudentInfo
{
int nID;
string strName;
} StudentInfo, *PStudentInfo; //學生資訊
struct sort
{
bool operator() (StudentInfo const &_A, StudentInfo const &_B)const
{
if(_A.nID < _B.nID)
return true;
if(_A.nID == _B.nID)
return _A.strName.compare(_B.strName) < 0;
return false;
}
};
int main()
{
//用學生資訊對映分數
map<StudentInfo, int, sort>mapStudent;
StudentInfo studentInfo;
studentInfo.nID = 1;
studentInfo.strName = "student_one";
mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));
studentInfo.nID = 2;
studentInfo.strName = "student_two";
mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));
map<StudentInfo, int>::reverse_iterator iter;
for(iter=mapStudent.rbegin();iter!= mapStudent.rend();iter++)
cout<<iter->second<<endl;
}
多重對映(multimap) <map>
允許鍵對有相等的次序的對映 <map>
比如在電話簿中相同的人可以有兩個以上電話號碼,檔案系統中可以將多個符號連結對映到相同的物理檔案,或DNS伺服器可以將幾個URLs對映到相同的IP地址。
查詢
1. 直接找到每種鍵值的所有元素的第一個元素的遊標。
通過函式:lower_bound( const keytype& x ), upper_bound( const keytype&x ) 可以找到比指定鍵值x的小的鍵值的第一個元素和比指定鍵值x大的鍵值的第一個元素。返回值為該元素的遊標。
細節:當到達鍵值x已經是最大時,upper_bound返回的是這個multimap的end遊標。同理,當鍵值x已經是最小了,lower_bound返回的是這個multimap的begin遊標。
2. 指定某個鍵值,進行遍歷
可以使用上面的lower_bound和upper_bound函式進行遊歷,也可以使用函式equal_range。其返回的是一個遊標對。遊標對pair::first是由函式lower_bound得到的x的前一個值,遊標對pair::second的值是由函式upper_bound得到的x的後一個值。
multimap<int,int>a;
a.insert(pair<int,int>(1,11));
a.insert(pair<int,int>(1,12));
a.insert(pair<int,int>(1,13));
a.insert(pair<int,int>(2,21));
a.insert(pair<int,int>(2,22));
a.insert(pair<int,int>(3,31));
a.insert(pair<int,int>(3,32));
multimap<int,int>::iterator p_map;
pair<multimap<int,int>::iterator,multimap<int,int>::iterator> ret;
for(p_map = a.begin() ; p_map != a.end();)
{
cout<<p_map->first<<" =>";
ret = a.equal_range(p_map->first);
for(p_map= ret.first; p_map != ret.second; ++p_map)
cout<<" "<< (*p_map).second;
cout<<endl;
}