STL中的常用的vector,map,set,Sort用法 STL中的常用的vector,map,set,Sort用法
C++的標準模板庫(Standard Template Library,簡(jiǎn)稱(chēng)STL)是一個(gè)容器和算法的類(lèi)庫。容器往往包含同一類(lèi)型的數據。STL中比較常用的容器是vector,set和map,比較常用的算法有Sort等。
.
一. vector
1.聲明:
一個(gè)vector類(lèi)似于一個(gè)動(dòng)態(tài)的一維數組。
vector<int> a; //聲明一個(gè)元素為int類(lèi)型的vector a
vectot<MyType> a; //聲明一個(gè)元素為MyType類(lèi)型的vector a
這里的聲明的a包含0個(gè)元素,既a.size()的值為0,但它是動(dòng)態(tài)的,其大小會(huì )隨著(zhù)數據的插入
和刪除改變而改變。
vector<int> a(100, 0); //這里聲明的是一已經(jīng)個(gè)存放了100個(gè)0的整數vector
2.向量操作
常用函數:
size_t size(); // 返回vector的大小,即包含的元素個(gè)數
void pop_back(); // 刪除vector末尾的元素,vector大小相應減一
void push_back(); //用于在vector的末尾添加元素
T back(); // 返回vector末尾的元素
void clear(); // 將vector清空,vector大小變?yōu)?
其他訪(fǎng)問(wèn)方式:
cout<<a[5]<<endl;
cout<<a.at(5)<<endl;
以上區別在于后者在訪(fǎng)問(wèn)越界時(shí)會(huì )拋出異常,而前者不會(huì )。
例:
int intarray[10];
vector<int> first_vector(intarray, intarray + 10);
vector<int> second_vector(first_vector.begin(),first_vector.end());
class man
{
public:
AnsiStirng id;
AnsiString mc;
}
vector<man> manList;
man thisman;
thisman.id="2001";
thisman.name="yourname";
manList.push_back thisman; //加入第一個(gè)元素
thisman.id="2002";
thisman.name="myname";
manList.push_back thisman; //加入第二個(gè)元素
manList.clear(); //清空
3.遍歷
(1). for(vector<datatype>::iterator it=a.begin(); it!=a.end();it++)
cout<<*it<<endl;
(2). for(int i=0;i<a.size;i++)
cout<<a[i]<<endl;
二. map
Map是STL的一個(gè)關(guān)聯(lián)容器,它提供一對一(其中第一個(gè)可以稱(chēng)為關(guān)鍵字,每個(gè)關(guān)鍵字只能在map中出現一次,第二個(gè)可能稱(chēng)為該關(guān)鍵字的值)的數據處理能力,由于這個(gè)特性
map內部的實(shí)現自建一顆紅黑樹(shù)(一種非嚴格意義上的平衡二叉樹(shù)),這顆樹(shù)具有對數據自動(dòng)排序的功能。
下面舉例說(shuō)明什么是一對一的數據映射。比如一個(gè)班級中,每個(gè)學(xué)生的學(xué)號跟他的姓名就存在著(zhù)一一映射的關(guān)系,這個(gè)模型用map可能輕易描述,
很明顯學(xué)號用int描述,姓名用字符串描述(本篇文章中不用char *來(lái)描述字符串,而是采用STL中string來(lái)描述),
下面給出map描述代碼:
1. 聲明方式:
Map<int, string> mapStudent;
2. 數據的插入
在構造map容器后,我們就可以往里面插入數據了。這里講三種插入數據的方法:
第一種:用insert函數插入pair數據
Map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, “student_one”));
第二種:用insert函數插入value_type數據
Map<int, string> mapStudent;
mapStudent.insert(map<int, string>::value_type (1, “student_one”));
第三種:用數組方式插入數據
Map<int, string> mapStudent;
mapStudent[1] = “student_one”;
mapStudent[2] = “student_two”;
3. map的大小
在往map里面插入了數據,我們怎么知道當前已經(jīng)插入了多少數據呢,可以用size函數:
Int nSize = mapStudent.size();
4. 數據的遍歷
第一種:應用前向迭代器
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
Cout<<iter->first<<” ”<<iter->second<<end;
第二種:應用反相迭代器
map<int, string>::reverse_iterator iter;
for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
Cout<<iter->first<<” ”<<iter->second<<end;
第三種:用數組方式
int nSize = mapStudent.size()
for(int nIndex = 1; nIndex <= nSize; nIndex++)
Cout<<mapStudent[nIndex]<<end;
5. 數據的查找(包括判定這個(gè)關(guān)鍵字是否在map中出現)
這里給出三種數據查找方法
第一種:用count函數來(lái)判定關(guān)鍵字是否出現,但是無(wú)法定位數據出現位置
第二種:用find函數來(lái)定位數據出現位置它返回的一個(gè)迭代器,
當數據出現時(shí),它返回數據所在位置的迭代器,如果map中沒(méi)有要查找的數據,它返回的迭代器等于end函數返回的迭代器
Int main()
{
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”));
map<int, string>::iterator iter;
iter = mapStudent.find(1);
if(iter != mapStudent.end())
{
Cout<<”Find, the value is ”<<iter->second<<endl;
}
Else
{
Cout<<”Do not Find”<<endl;
}
}
第三種:這個(gè)方法用來(lái)判定數據是否出現
Lower_bound函數用法,這個(gè)函數用來(lái)返回要查找關(guān)鍵字的下界(是一個(gè)迭代器)
Upper_bound函數用法,這個(gè)函數用來(lái)返回要查找關(guān)鍵字的上界(是一個(gè)迭代器)
例如:map中已經(jīng)插入了1,2,3,4的話(huà),如果lower_bound(2)的話(huà),返回的2,而upper-bound(2)的話(huà),返回的就是3
Equal_range函數返回一個(gè)pair,pair里面第一個(gè)變量是Lower_bound返回的迭代器,pair里面第二個(gè)迭代器是Upper_bound返回的迭代器,如果這兩個(gè)迭代器相等的話(huà),則說(shuō)明map中不出現這個(gè)關(guān)鍵字,程序說(shuō)明
mapPair = mapStudent.equal_range(2);
if(mapPair.first == mapPair.second)
cout<<”Do not Find”<<endl;
6. 數據的清空與判空
清空map中的數據可以用clear()函數,判定map中是否有數據可以用empty()函數,它返回true則說(shuō)明是空map
7. 數據的刪除
這里要用到erase函數,它有三個(gè)重載了的函數
迭代器刪除
iter = mapStudent.find(1);
mapStudent.erase(iter);
用關(guān)鍵字刪除
Int n = mapStudent.erase(1);//如果刪除了會(huì )返回1,否則返回0
用迭代器,成片的刪除
一下代碼把整個(gè)map清空
mapStudent.earse(mapStudent.begin(), mapStudent.end());
//成片刪除要注意的是,也是STL的特性,刪除區間是一個(gè)前閉后開(kāi)的集合
8. 其他一些函數用法
這里有swap,key_comp,value_comp,get_allocator等函數,有興趣的話(huà)可以自個(gè)研究
三. set
set是集合,set中不會(huì )包含重復的元素,這是和vector的區別。
定義:
定義一個(gè)元素為整數的集合a,可以用
set<int> a;
基本操作:
對集合a中元素的有
插入元素:a.insert(1);
刪除元素(如果存在):a.erase(1);
判斷元素是否屬于集合:if (a.find(1) != a.end()) ...
返回集合元素的個(gè)數:a.size()
將集合清為空集:a.clear()
集合的并,交和差
set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
(注意在此前要將c清為空集)。
注意:
很重要的一點(diǎn),為了實(shí)現集合的快速運算,set的實(shí)現采用了平衡二叉樹(shù),因此,set中的元素必須是可排序的。如果是自定義的類(lèi)型,那在定義類(lèi)型的同時(shí)必須給出運算符<的定義
四. Sort
Sort顧名思義就是排序
用法:
單關(guān)鍵字:
對于vector a來(lái)說(shuō)
Sort(&a[0], &a[N]); //N=a.size() 將a中元素遞增排序。
多關(guān)鍵字:
我們也可以利用類(lèi)pair
vector< pair<int,int> > a; // 注意這里兩個(gè)> >中間必須有一個(gè)空格,否則編譯器會(huì )當是運算符>>
例如:
int N,x,y; cin >> N;
for(int i=0;i<N;++i) {
cin >> x >> y;
a.push_back(make_pair(x,y)); // make_pair用于創(chuàng )建pair對象
}
sort(&a[0], &a[N]);
注意:
對于我們自己定義的類(lèi)或結構,系統一般不能替我做比較運算,需要我們自己定義相應的運算符<
bool operator<(const MyType &x, const MyType &y)
{
// Return true if x<y, false if x>=y