或許你已經把 c++ 作為主要的程式語言用來解決 topcoder 上的問題。這意味著你已經簡單使用過了 stl,因為陣列和字串都是作為 stl 物件傳遞給函式。也許你已經注意到了,很多程式設計師寫**比你快得多,也更簡潔。
或許你還不是但想成為一名 c++ 程式猿,因為這種程式語言功能很強大還有豐富的庫(也許是因為在 topcoder 的練習室裡和競賽中看到了很多非常精簡的解決方案)。
無論過去如何,這篇文章都會有所幫助。在這裡,我們將回顧標準模板庫(standard template library—stl,乙個非常有用的工具,有時甚至能在演算法競賽中為你節省大量時間)的一些強大特性。
要熟悉 stl,最簡單的方式就是從容器開始。
容器
無論何時需要操作大量元素,都會用到某種容器。c語言只有一種內建容器:陣列。
問題不在於陣列有侷限性(例如,不可能在執行時確定陣列大小)。相反,問題主要在於很多任務需要功能更強大的容器。
例如,我們可能需要乙個或多個下列操作:
向容器新增某種字串
從容器中移除乙個字串
確定容器中是否存在某個字串
從容器中返回一些互不相同的元素
對容器進行迴圈遍歷,以某種順序獲取乙個附加字串列表。
當然,我們可以在乙個普通陣列上實現這些功能。但是,這些瑣碎的實現會非常低效。你可以建立樹結構或雜湊結構來快速解決問題,但是想想:這種容器的實現是取決於即將儲存的元素型別嗎?例如,我們要儲存平面上的點而不是字串的話,是不是要重寫這個模組才能實現功能?
如果不是,那我們可以一勞永逸地為這種容器開發出介面,然後對任何資料型別都能使用。簡言之,這就是stl 容器的思想。
前言
程式要使用 stl 時,應包含(#include)適當的標準標頭檔案。對大部分容器來說,標準標頭檔案的名稱和容器名一致,且不需副檔名。比如說,如果你要用棧(stack),只要在程式最開頭新增下面這行**:
#include
容器型別(還有演算法、運算子和所有stl也一樣)並不是定義在全域性命名空間,而是定義在乙個叫「std」的特殊命名空間裡。在包含完所有標頭檔案之後,寫**之前新增下面這一行:
using
namespace
std;
還有另乙個很重要的事情要記住:容器型別也是模板引數。在**中用「尖括號」(『<』/』>』)指明模板引數。比如:
vector
n;
如果要進行巢狀式的構造,確保「方括號」之間不是緊挨著——留出乙個空格的位置。(譯者:c++11新特性支援兩個尖括號之間緊挨著,不再需要加空格)
vector
> correctdefinition;
vector
> wrongdefinition;
//wrong: compiler may be confused by 'operator >>'
一、vector
最簡單的 stl 容器就是 vector。vector 只是乙個擁有擴充套件功能的陣列。順便說一下,vector 是唯一向後相容 c **的容器——這意味著 vector 實際上就是陣列,只是擁有一些額外特性。
vector
v(10); //把』v』宣告成乙個存放了 10 個 vector型別元素的陣列,初始化為空
//實際上,當你敲下vectorv就建立了乙個空 vector
for(int i = 0; i < 10; i++)
vector 最常使用的特性就是獲取容器大小
int elements_count = v.size()
有兩點要注意:首先,size() 函式返回的值是無符號的,這點有時會引起一些問題。其次,如果你想知道容器是否為空,把 vector 的 size() 返回值和0比較不是乙個好的做法。你最好使用 empty() 函式.
另乙個 vector 中經常使用的函式是 push_back。push_back 函式向 vector 尾部新增乙個元素,容器長度加 1。思考下面這個例子:
vector
v1;
for(int i=1; i<10; i *= 2)
for(unsigned
int i=0; icout
}
別擔心記憶體分配問題——vector 不會一次只分配乙個元素的空間。相反,每次用 push_back 新增新元素時,vector 分配的記憶體空間總是比它實際需要的更多。你應該擔心的唯一一件事情是記憶體使用情況。
當你需要重新改變 vector 的大小時,使用 resize() 函式:
vector
v(20);
for(int i=0; i<20; i++)
v.resize(25);//重新改變 vector 的大小
for(int i=20; i<25; i++)
resize() 函式讓 vector 只儲存所需個數的元素。如果你需要的元素個數少於 vector 當前儲存的個數,剩餘那些元素就會被刪除。如果你要求 vector 變大,使用這個函式也會擴大它的長度,並用 0 填充新建立的元素。
注意,如果在使用了 resize() 後又用了 push_back(),那新新增的元素就會位於新分配記憶體的後面,而不是被放入新分配的記憶體當中。上面的例子得到的 vector 大小是25,如果在第二個迴圈中使用 push_back(),那vector 的大小最後會是30。
int main()
v.resize(25); /
for(int i=20; i<25; i++)
for(unsigned
int i=0; icout
<" ";
}cout
0;}
結果:
123
4567
891011
1213
1415
1617
1819200
0000
2021
2223
2430
//大小變為30
使用clear() 函式來清空 vector。這個函式使 vector 包含 0 個元素。它並不是讓所有元素的值為0——注意——它是完全刪除所有元素,成為空容器。
向 vector 新增資料的最簡單方式是使用 push_back()。但是,萬一我們想在除了尾部以外的地方新增資料呢?insert() 函式可以實現這個目的。同時還有 erase() 函式來刪除元素。但我們得先講講迭代器。
你還應該記住另乙個非常重要的事情:當 vector 作為引數傳給某個函式時,實際上是複製了這個 vector(也就是值傳遞)。在不需要這麼做的時候建立新的 vector 可能會消耗大量時間和記憶體。實際上,很難找到乙個任務需要在傳遞 vector 為引數時對其進行複製。因此,永遠不要這麼寫:
void some_function(vector
v) //
相反,使用下面的構造方法(引用傳遞):
void some_function(const
vector
&v) //!!!!!!
如果在函式裡要改變 vector 中的元素值,那就去掉『const』修飾符。
int modify_vector(vector
&v)
STL 標準模板庫)
此篇只是乙個目錄,將分成單篇去完成 stl 主要有三個部分組成 容器,迭代器,演算法。順序容器 向量 vector 雙端佇列 dequeue 表 list ps copy 方法 關聯容器 集合 set 多重集合 multiset 對映 map 多重對映 multimap 容器介面卡 棧 stack ...
Stl(標準模板庫)
stl 標準模板庫 stl的目的是標準化元件,這樣就不用重新開發,可以使用現成的元件。我們常用到的stl容器有vector list deque map multimap set和multiset。1.簡單概括 如果需要高效的隨機訪問,不在乎插入和刪除的效率,使用vector 類似陣列 2 如果需要...
STL標準模板庫
stl標準模板庫 一。概述 c 內建的標準模板庫stl可以分為以下6大類 1.容器 2.迭代器 3.空間分配器 4.介面卡 5.演算法 6.仿函式 1.容器 概念 用來管理一組元素 分類 序列式容器 sequence containers 每個元素都有固定位置 取決於插入時機和地點,和元素值無關。v...