Effective STL學習筆記 條款44

2021-08-13 02:52:14 字數 1949 閱讀 7227

有些容器擁有和stl演算法同名的成員函式。關聯容器提供了count、find、lower_bound、upper_bound和equal_range,而list提供了remove、remove_if、unique、sort、merge和reverse。大多數情況下,你應該用成員函式代替演算法。這樣做有兩個理由。首先,成員函式更快。其次,比起演算法來,它們與容器結合得更好(尤其是關聯容器)。那是因為同名的演算法和成員函式通常並不是是一樣的。我們以對關聯容器的實驗開始。假如有乙個set,它容納了一百萬個元素,而你想找到元素727的第乙個出現位置(如果存在的話)。這兒有兩個最自然的方法來執行搜尋:

set

s; // 建立set,放入1,000,000個資料

...set

::iterator i = s.find(727); // 使用find成員函式

if (i != s.end()) ...

set::iterator i = find(s.begin(), s.end(), 727); // 使用find演算法

if (i != s.end()) ...

find成員函式執行花費對數時間,所以不管727是否存在於此set中,set::find只需執行不超過40次比較來查詢它,而一般只需要大約20次。相反,find演算法執行花費線性時間,所以如果727不在此set中,它需要執行1,000,000次比較。即使727在此set中,也平均需要執行500,000次比較來找到它。效率得分如下:find成員:大約40(最壞的情況)至大約20(平均情況)find演算法:1,000,000(最壞的情況)至500,000(平均情況)和高爾夫比賽一樣,分值低的贏。正如你所見,這場比賽結果沒什麼可說的。我必須對find成員函式所需的比較次數表示小小的謹慎,因為它有些依賴於關聯容器的實現。絕大部分的實現是使用的紅黑樹——平衡樹的一種——失衡度可能達到2。在這樣的實現中,對一百萬個元素的set進行搜尋所需最多的比較次數是38次。但對絕大部分的搜尋情況而言,只需要不超過22次。乙個基於完全平衡樹的實現絕不需要超過21次比較,但在實踐中,完全平衡樹的效率總的來說不如紅黑樹。這就是為什麼大多數的stl實現都使用紅黑樹。

另一方面,如果你真的關心效率,你可以採用條款23中的技巧,聯合條款34中講的對數時間搜尋演算法。相對於效能的提公升,這只是乙個很小的代價。再者,如果你真的在乎效率,你應該考慮非標準的雜湊容器(在條款25進行了描述),只是,你將再次面對相等和等價的區別。

對於標準的關聯容器,選擇成員函式而不是同名的演算法有幾個好處。首先,你得到的是對數時間而不是線性時間的效能。其次,你判斷兩個元素「相同」使用的是等價,這是關聯容器的預設定義。第三,當操縱map和multimap時,你可以自動地只處理key值而不是(key, value)對。這三點給了優先使用成員函式完美的鐵甲。讓我們轉到list的與演算法同名的成員函式身上。這裡的故事幾乎全部是關於效率的。每個被list作了特化的演算法(remove、remove_if、unique、sort、merge和reverse)都要拷貝物件,而list的特別版本什麼都沒有拷貝;它們只是簡單地操縱連線list的節點的指標。演算法和成員函式的演算法複雜度是相同的,但如果操縱指標比拷貝物件的代價小的話,list的版本應該提供更好的效能。牢牢記住這一點很重要:list成員函式的行為和它們的演算法兄弟的行為經常不相同。正如條款32所解釋的,如果你真的想從容器中清除物件的話,呼叫remove、remove_if和unique演算法後,必須緊接著呼叫erase函式;但list的remove、remove_if和unique成員函式真的去掉了元素,後面不需要接著呼叫erase。在sort演算法和list的sort成員函式間的乙個重要區別是前者不能用於list。作為單純的雙向迭代器,list的迭代器不能傳給sort演算法。merge演算法和list的merge成員函式之間也同樣存在巨大差異。這個演算法被限制為不能修改源範圍,但list::merge總是修改它的宿主list。所以,你明白了吧。當面臨著stl演算法和同名的容器成員函式間進行選擇時,你應該盡量使用成員函式。幾

乎可以肯定它更高效,而且它看起來也和容器的慣常行為整合得更好。

—-以上全文來自書上 條款44

Effective STL學習筆記 條款20

在這裡我們強調的是指標,先個例子 set ssp ssp.insert new ssp.insert new string lemon ssp.insert new string banana ssp.insert new string pear for auto str ssp 按照我們正常的想法...

Effective STL學習筆記 條款23

直接進入主題,為什麼會考慮使用vector代替關聯容器呢,可能有這樣的場景,一對關聯的資料,而時使用時要求資料查詢速度很快。當然我們必須知道有序的vector的缺點就是他必須保持有序,乙個新item插入可能造成其他元素的移動。所以這種場景可能在幾乎不插入和刪除時考慮。乙個例子 using pair ...

Effective STL學習筆記 條款30

看個例子 我們使用transform函式給乙個容器承載計算結果 vector src 待計算的資料 vector res 計算結果 src.push back 0 src.push back 1 src.push back 2 src.push back 3 std transform src.be...