聲明:
本文綜合
http://blog.csdn.net/conanswp/article/details/23297441
http://www.cnblogs.com/LonelyEnvoy/p/5850679.html
http://blog.csdn.net/bingxuebage/article/details/5729064
而編輯。
1.基本容器介紹
C++中有兩種類型的容器:順序容器和關聯容器。順序容器主要有vector、list、deque等。其中vector表示一段連續的內存,基於數組實現,list表示非連續的內存,基於鏈表實現,deque與vector類似,但是對首元素提供插入和刪除的雙向支持。關聯容器主要有map和set。map是key-value形式,set是單值。map和set只能存放唯一的key,multimap和multiset可以存放多個相同的key。
容器類自動申請和釋放內存,因此無需new和delete操作。
通常使用步驟如下:
大致有下面6個步驟:
1.添加相應的頭文件(如 #include <list> )( 注意,沒有 .h )
2.添加std命名空間(用 using namespace std; )
3.賦予模板具體的使用類型(如 typedef list<string> LISTSTR; )
4.實例化模板(如 LISTSTR test; )
5.實例化遊標(如 LISTSTR::iterator i; )
6.通過迭代器對象訪問模板對象,例如
// 逐個輸出鏈表test中的元素
for ( i = test.begin(); i != test.end(); ++i )
cout << *i << " ";
容器模板中常用的函數有:
assign() //賦值
empty() //容器爲空則返回非0值
erase() //刪除指定位置或指定範圍內的元素
push_front() //從容器頭部插入元素
push_back() //從容器尾部插入元素
pop_front() //刪除第一個元素
pop_back() // 刪除最後一個元素
back() //返回最後一個元素的引用
front() //返回第一個元素的引用
begin() //返回指向第一個元素的遊標 (與迭代器配合使用)
end() //返回指向最後一個元素的後一個位置的遊標 (最後1個元素再加1) (與迭代器配合使用)
1.1 vector
vector基於模板實現,需包含頭文件vector。
1.1.1 定義和初始化
//1.定義和初始化
vector<int> vec1; //默認初始化,vec1爲空
vector<int> vec2(vec1); //使用vec1初始化vec2
vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2,效果同上
vector<int> vec4(10); //10個值爲0的元素
vector<int> vec5(10,4); //10個值爲4的元素
1.1.2 常用方法
vec1.push_back(100); //添加元素
int size = vec1.size(); //元素個數
bool isEmpty = vec1.empty(); //判斷是否爲空
cout<<vec1[0]<<endl; //取得第一個元素
vec1.insert(vec1.end(),5,3); //從vec1.back位置插入個值爲的元素
vec1.pop_back(); //刪除末尾元素
vec1.erase(vec1.begin(),vec1.end());//刪除之間的元素,其他元素前移
cout<<(vec1==vec2)?true:false; //判斷是否相等==、!=、>=、<=...
vector<int>::iterator iter = vec1.begin(); //獲取迭代器首地址
vector<int>::const_iterator c_iter = vec1.begin(); //獲取const類型迭代器
vec1.clear(); //清空元素
1.1.3 遍歷
//下標法
int length = vec1.size();
for(int i=0;i<length;i++)
{
cout<<vec1[i];
}
cout<<endl<<endl;
//迭代器法
vector<int>::const_iterator iterator = vec1.begin();
for(;iterator != vec1.end();iterator++)
{
cout<<*iterator;
}
1.1.4 例程
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
int ar[10] = { 12, 45, 234, 64, 12, 35, 63, 23, 12, 55 };
char* str = "Hello World";
int main()
{
vector <int> vec1(ar, ar + 10); //first=ar,last=ar+10,不包括ar+10
vector < char > vec2(str, str + strlen(str)); //first=str,last= str+strlen(str),
//打印vec1和vec2,const_iterator是迭代器,後面會講到
//size()是vector的一個成員函數
cout << "vec1:" << endl;
cout << "size is "<<vec1.size() << endl;
/* for (int i=0; i<vec1.size(); i++)cout << vec1[i];*/
/* 這種方式也可以*/
for (vector<int>::const_iterator p = vec1.begin(); p != vec1.end(); p++)
cout << *p<<" ";
cout << endl;
cout << "size is " << vec2.size() << endl;
cout <<"vec2:" << endl;
for (vector< char >::const_iterator p1 = vec2.begin(); p1 != vec2.end(); p1++)
cout << *p1;
cout << endl;
return 0;
}
爲了幫助理解向量的概念,這裏寫了一個小例子,其中用到了vector的成員函數:begin(),end(),push_back(),assign(),front(),back(),erase(),empty(),at(),size()。
#include <iostream>
#include <vector>
using namespace std;
//使用typedef自定義類型INTVECTOR
typedef vector<int> INTVECTOR;
//測試vector容器的功能
int main()
{
//vec1對象初始爲空
INTVECTOR vec1;
//vec2對象最初有10個值爲6的元素
INTVECTOR vec2(10, 6);
//vec3對象最初有3個值爲6的元素,拷貝構造
INTVECTOR vec3(vec2.begin(), vec2.begin() + 3);
//聲明一個名爲i的雙向迭代器
INTVECTOR::iterator i;
//從前向後顯示vec1中的數據
cout << "vec1.begin()--vec1.end():" << endl;
for (i = vec1.begin(); i != vec1.end(); ++i)
cout << *i << " ";
cout << endl;
//從前向後顯示vec2中的數據
cout << "vec2.begin()--vec2.end():" << endl;
for (i = vec2.begin(); i != vec2.end(); ++i)
cout << *i << " ";
cout << endl;
//從前向後顯示vec3中的數據
cout << "vec3.begin()--vec3.end():" << endl;
for (i = vec3.begin(); i != vec3.end(); ++i)
cout << *i << " ";
cout << endl;
//測試添加和插入成員函數,vector不支持從前插入
vec1.push_back(2);//從後面添加一個成員
vec1.push_back(4);
vec1.insert(vec1.begin() + 1, 5);//在vec1第一個的位置(vec1[1])上插入成員5
//從vec1第一的位置開始插入vec3的所有成員
vec1.insert(vec1.begin() + 1, vec3.begin(), vec3.end());
cout << "after push() and insert() now the vec1 is:" << endl;
for (i = vec1.begin(); i != vec1.end(); ++i)
cout << *i << " ";
cout << endl;
//測試賦值成員函數
vec2.assign(8, 1); // 重新給vec2賦值,8個成員的初始值都爲1
cout << "vec2.assign(8,1):" << endl;
for (i = vec2.begin(); i != vec2.end(); ++i)
cout << *i << " ";
cout << endl;
//測試引用類函數
cout << "vec1.front()=" << vec1.front() << endl;//vec1第零個成員
cout << "vec1.back()=" << vec1.back() << endl;//vec1的最後一個成員
cout << "vec1.at(4)=" << vec1.at(4) << endl;//vec1的第五個成員
cout << "vec1[4]=" << vec1[4] << endl;
//測試移出和刪除
vec1.pop_back();//將最後一個成員移出vec1
vec1.erase(vec1.begin() + 1, vec1.end() - 2);//刪除成員,減幾後邊留幾個
cout << "vec1.pop_back() and vec1.erase():" << endl;
for (i = vec1.begin(); i != vec1.end(); ++i)
cout << *i << " ";
cout << endl;
//顯示序列的狀態信息
cout << "vec1.size(): " << vec1.size() << endl;//打印成員個數
cout << "vec1.empty(): " << vec1.empty() << endl;//清空
}
1.2 deque
deque容器類與vector類似,支持隨機訪問和快速插入刪除,它在容器中某一位置上的操作所花費的是線性時間。與vector不同的是,deque還支持從開始端插入數據:push_front()。其餘類似vector操作方法的使用。
此外deque也不支持與vector的capacity()、reserve()類似的操作。
1.2.1 例程
#include <iostream>
#include <deque>
using namespace std;
typedef deque<int> INTDEQUE;//用typedef定義
//從前向後顯示deque隊列的全部元素的子函數
void put_deque(INTDEQUE deque, char *name)
{
INTDEQUE::iterator pdeque;//定義遊標
cout << "The contents of " << name << " : ";
for (pdeque = deque.begin(); pdeque != deque.end(); pdeque++)
cout << *pdeque << " ";//注意有 "*"號哦,沒有"*"號的話會報錯
cout << endl;
}
//測試deqtor容器的功能
int main()
{
//deq1對象初始爲空
INTDEQUE deq1;
//deq2對象最初有10個值爲6的元素
INTDEQUE deq2(10, 6);
//聲明一個名爲i的雙向迭代器變量
INTDEQUE::iterator i;
//從前向後顯示deq1中的數據
put_deque(deq1, "deq1");
//從前向後顯示deq2中的數據
put_deque(deq2, "deq2");
//從deq1序列後面添加兩個元素
deq1.push_back(2);
deq1.push_back(4);
cout << "deq1.push_back(2) and deq1.push_back(4):" << endl;
put_deque(deq1, "deq1");
//從deq1序列前面添加兩個元素
deq1.push_front(5);
deq1.push_front(7);
cout << "deq1.push_front(5) and deq1.push_front(7):" << endl;
put_deque(deq1, "deq1");
//在deq1序列中間插入數據
deq1.insert(deq1.begin() + 1, 3, 9);
cout << "deq1.insert(deq1.begin()+1,3,9):" << endl;
put_deque(deq1, "deq1");
//測試引用類函數
cout << "deq1.at(4)=" << deq1.at(4) << endl;
cout << "deq1[4]=" << deq1[4] << endl;
deq1.at(1) = 10;
deq1[2] = 12;
cout << "deq1.at(1)=10 and deq1[2]=12 :" << endl;
put_deque(deq1, "deq1");
//從deq1序列的前後各移去一個元素
deq1.pop_front();
deq1.pop_back();
cout << "deq1.pop_front() and deq1.pop_back():" << endl;
put_deque(deq1, "deq1");
//清除deq1中的第2個元素
deq1.erase(deq1.begin() + 1);
cout << "deq1.erase(deq1.begin()+1):" << endl;
put_deque(deq1, "deq1");
//對deq2賦值並顯示
deq2.assign(8, 1);
cout << "deq2.assign(8,1):" << endl;
put_deque(deq2, "deq2");
return 0;
}
1.3 list
List是stl實現的雙向鏈表,與 向量(vectors)相比, 它允許快速的插入和刪除,但是隨機訪問卻比較慢。需要添加頭文件list。
只能順序訪問(從前向後或者從後向前)。與前面兩種容器類有一個明顯的區別就是:它不支持隨機訪問。要訪問表中某個下標處的項需要從表頭或表尾處(接近該下標的一端)開始循環。而且缺少下標預算符:operator[]。
1.3.1 定義和初始化
定義和初始化
list<int> lst1; //創建空list
list<int> lst2(3); //創建含有三個元素的list
list<int> lst3(3,2); //創建含有三個元素的list
list<int> lst4(lst2); //使用lst2初始化lst4
list<int> lst5(lst2.begin(),lst2.end()); //同lst4
1.3.2 常用操作方法
常用操作方法
lst1.assign(lst2.begin(),lst2.end()); //分配值
lst1.push_back(10); //添加值
lst1.pop_back(); //刪除末尾值
lst1.begin(); //返回首值的迭代器
lst1.end(); //返回尾值的迭代器
lst1.clear(); //清空值
bool isEmpty1 = lst1.empty(); //判斷爲空
lst1.erase(lst1.begin(),lst1.end()); //刪除元素
lst1.front(); //返回第一個元素的引用
lst1.back(); //返回最後一個元素的引用
lst1.insert(lst1.begin(),3,2); //從指定位置插入個
lst1.rbegin(); //返回第一個元素的前向指針
lst1.remove(2); //相同的元素全部刪除
lst1.reverse(); //反轉
lst1.size(); //含有元素個數
lst1.sort(); //排序
lst1.unique(); //刪除相鄰重複元素
1.3.3 遍歷
和前兩個類似
//迭代器法
for(list<int>::const_iterator iter = lst1.begin();iter != lst1.end();iter++)
{
cout<<*iter;
}
cout<<endl;
1.3.4 例程
merge函數的作用是:將兩個有序的序列合併爲一個有序的序列。函數參數
merge(first1,last1,first2,last2,result,compare)
firs1t爲第一個容器的首迭代器,last1爲第一個容器的末迭代器,first2爲第二個容器的首迭代器,last2爲容器的末迭代器,result爲存放結果的容器,comapre爲比較函數(可略寫,默認爲合併爲一個升序序列)。
#include <iostream>
#include <string>
#include <list>
using namespace std;
void PrintIt(list<int> n)
{
for (list<int>::iterator iter = n.begin(); iter != n.end(); ++iter)
cout << *iter << " ";//用迭代器進行輸出循環
}
int main()
{
list<int> listn1, listn2; //給listn1,listn2初始化
listn1.push_back(123);
listn1.push_back(0);
listn1.push_back(34);
listn1.push_back(1123); //now listn1:123,0,34,1123
listn2.push_back(100);
listn2.push_back(12); //now listn2:12,100
listn1.sort();
listn2.sort(); //給listn1和listn2排序
//now listn1:0,34,123,1123 listn2:12,100
cout << "listn1 is "<<endl;
PrintIt(listn1);
cout << endl;
cout << "listn2 is "<<endl;
PrintIt(listn2);
cout << endl;
cout << "after merge is " << endl;
listn1.merge(listn2); //合併兩個排序列表後,listn1:0,12,34,100,123,1123
PrintIt(listn1);
cout << endl;
}