Prefer C++ (二) (轉)

amyz發表於2007-08-14
Prefer C++ (二) (轉)[@more@]

4、超強的標準庫:namespace prefix = o ns = "urn:schemas--com::office" />

 

標準庫裡有什麼呢,同C標準庫最大的不同應該是STL。有了STL,不必再寫大多的標準資料結構和演算法,並且可獲得非常高的。

Stl中有幾個基本的概念:

容器:可容納各種資料型別的資料結構。

迭代器:可依次存取容器中資料的結構

演算法:透過迭代器對容器進行某種操作的

舉個容易理解的例子:

陣列就是個容器,而指標就是迭代器。

 

接下來將用幾小節專門描述stl的概貌。

 

下面所提到的內容多取自《C++ 標準庫》一書,以下將不另行說明。

4.1 stl中的容器

 

標準容器有7種,不同實現有相應的擴充。

7種容器對應的模型如下:

 

vector

 

其中箭頭表示資料增長方向。實際上就是個動態陣列。在尾端增刪元素具有較佳的效能。

 

Deque

 

在兩端增刪元素具有較佳的效能。

 


 

List 

雙向連結串列,在任何位置增刪元素都具有相近的效能。

上述三種容器稱為序列式容器(sequence container)。元素的插入位置同元素的值無關。

 

 


 

Set/Multiset:

 

 

 

 

此種容器內的元素是已序的,插入任何元素,都按相應的排序準則來確定其位置。

Set中不允許相同元素,multiset中允許存在相同的元素。

 

Map/Multimap:

 

 

 

 

 

Map同Multimap的不同在於是否允許相同的元素。

Map與Set的不同在於Map中存放的是成對的key/value。

並根據key對元素進行排序。

 

上述四種容器稱為關聯式容器(Associative Container)。特點是在查詢時具有非常好的效能。

以上述7種容器為基礎,stl還實現了Stacks,Queues,Priority Queues。

用Map來舉個例子:

typedef map mapforaccount;

//定義

mapforaccount lunch;

//賦值

lunch[“陳勇”]=50.00;

lunch[“林立堅”]=35.00;

lunch[“陳陣”]=45.00;

lunch[“czzs”]=65.00;

//列印

mapforaccount::iterator pos;

for(pos=lunch.begin();pos!=lunch.end();++pos)

{

  cout<first<

  <second<

}

上述各種容器都有一些成員函式,支援一些基本的操作和對某些演算法進行。

不同的容器的成員函式並不完全相同。

其中:

 

l  所有容器都支援以下運算子:==,!=,,<=,>=。當且僅當兩個容器型別相同,元素數目相同,元素順序相同,並每個元素都相等時==為true。

小於的情況以字典序進行判定。

l  insert(),push_front(),push_back()等新增成員得函式

l  remove(),pop_front(),pop_back(),[],at()等刪除及讀取元素的函式。

總之這些函式使你對容器中元素得讀寫更為方便。

 

剩下得成員函式,諸如sort(),merge()等是容器根據本身特性對某些演算法得最佳化,實現與下面所講得演算法相同得功能。

 

可作為動態陣列的vector 非常的常用,以他為例來看一下容器都可以為我們做些什麼。

 

構造與析構

vector c  產生一個空vector

vector c1(c2)  生成一個c2的副本

vector c(n)  產生一大小為n的容器,用預設建構函式生成其中每個元素的值

vector c(n,elem)  產生一大小為n的容器,其中每個元素的值都是elem

vector c(beg,end)  產生一個以[beg,end]區間為初值的vector

c.~vector()  銷燬所有元素,並釋放

 

非變動性操作

c.size()  返回容器中元素的數量

c.empty()  大小是否為0

c.max_size()   可容納元素的最大數量

capacity()  重新分配空間前所能容納的元素的最大數量

reserve()  保留一定大小的空間

c1==c2

c1!=c2

c1

c1>c2

c1<=c2

c1>=c2

 

賦值操作

c1=c2  將c2的元素全部複製給c1

c.assign(n,elem)  用n個元素填充c

c.assign(beg,end)  用指定區間的內容填充c

c1.s(c2)  c1,c2的內容互換

swap(c1,c2)  同上為全域性函式

 

元素的存取

c.at[idx]  返回idx所表示的元素,檢查邊界

c[idx]  同上但不檢查邊界

c.front()  返回第一個元素,不檢查其是否存在

c.back()  返回最後一個元素,不檢查其是否存在

 

迭代器相關函式

c.begin()  返回指向第一個元素的隨機存取迭代器

c.end()  返回指向最後一個元素的隨機存取迭代器

c.rbegin()  返回指向第一個元素的逆向迭代器

c.rend()  返回指向最後一個元素的逆向迭代器

 

安插及移除操作

c.insert(pos,elem)  在pos位置插入一個新元素副本,並返回新元素位置

c.insert(pos,n,elem)  在pos位置插入n個新元素副本

c.insert(pos,beg,end)  在pos位置插入[beg,end)區間內所有元素的副本

c.push_back(elem)  在尾部新增一個elem

c.pop_back()  移除最後一個元素,不回傳

c.erase(pos)  移除pos位置的元素,返回下一元素的位置

c.erase(beg,end)  移除[beg,end)區間內所有元素,並傳回新位置

c.resize(num)   將元素數量改為num

c.clear()  移除所有元素

 

 

看如下的程式段:

這是為說明vector各個成員函式的使用而做的。

 

typedef vector stringarray;

 

// PRINT_ELEMENTS負責輸出容器中的所有元素

template

inline void PRINT_ELEMENTS(const T& coll, const char* cptcstr=" ")

  {

  typename T::const_iterator pos;

 

  cout<< cptcstr<< endl;

 

  for(pos=coll.begin();pos!=coll.end();++pos)

  {

  cout<< *p<

  cout<

  }

  }

int main()

  {

  stringarray filename;//empty vector

 

//在容器中的元素數量達到10之前不用重新分配記憶體

  filename.reserve(10);

 

  filename.push_back("c: est1.emf");

  filename.push_back("c: est2.emf");

  filename.push_back("c: est3.emf");

  filename.push_back("c: est4.emf");

  filename.push_back("c: est5.emf");

  filename.push_back("c: est6.emf");

 

  PRINT_ELEMENTS(filename,"After push_back:");

 

  cout<< "max_size():" <

  cout<< "size():" <

  cout<< "capacity():" <

//在第一個元素的位置插入

  filename.insert(filename.begin(),"d:ie.emf");

  PRINT_ELEMENTS(filename,"After insert:");

 

  cout<< "Now the first element is: "<< filename[0] << endl;

// back()返回最後一個元素

  cout<< "Now the last element is: "<< filename.back() << endl;

 

//為tempfilename賦初值

  stringarray tempfilename=filename;

 

  PRINT_ELEMENTS(tempfilename,"Before erase:");

//刪除前三個元素

  tempfilename.erase(tempfilename.begin(),tempfilename.begin()+3);

 

  PRINT_ELEMENTS(tempfilename,"after erase:");

//刪除最後一個元素

  tempfilename.pop_back();

 

  PRINT_ELEMENTS(tempfilename,"after pop_back():");

 

//來個恐怖的,這個說明vector在記憶體中是連續存放的

  vector v;

  v.resize(41);

  strcpy(&v[0],"this is a test");

  printf("%s ",&v[0]); 

  return 0;

  }

輸出結果為:

After push_back:

c: est1.emf

c: est2.emf

c: est3.emf

c: est4.emf

c: est5.emf

c: est6.emf

max_size():357913941

size():6

capacity():10

After insert:

d:ie.emf

c: est1.emf

c: est2.emf

c: est3.emf

c: est4.emf

c: est5.emf

c: est6.emf

Now the first element is: d:ie.emf

Now the last element is: c: est6.emf

Before erase:

d:ie.emf

c: est1.emf

c: est2.emf

c: est3.emf

c: est4.emf

c: est5.emf

c: est6.emf

after erase:

c: est3.emf

c: est4.emf

c: est5.emf

c: est6.emf

after pop_back():

c: est3.emf

c: est4.emf

c: est5.emf

this is a test

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-956780/,如需轉載,請註明出處,否則將追究法律責任。

相關文章