STL與泛型編程 week 1 (Boolan)

課程目標(biāo)

  • level 0: 淺嘗C++標(biāo)準(zhǔn)庫
  • level 1: 深入認(rèn)識(shí)C++標(biāo)準(zhǔn)庫 (胸中自有丘壑)
  • level 2: 良好使用C++標(biāo)準(zhǔn)庫
  • level 3: 擴(kuò)充C++標(biāo)準(zhǔn)庫

C++ Standard Library vs. Standard Template Library

  • C++ Standard Library (C++標(biāo)準(zhǔn)庫)
  • Standard Template Library (STL, 標(biāo)準(zhǔn)模板庫) (note: STL 可以看成是C++標(biāo)準(zhǔn)庫的一個(gè)子集)

標(biāo)準(zhǔn)庫以header files形式呈現(xiàn):

  • C++標(biāo)準(zhǔn)庫的header files不帶副檔名(.h), 例如#include<vector>
  • 新式C header files不帶副名檔.h, 例如#include<cstdio>
  • 舊式C header files(帶有副檔名.h)仍然可用, 例如#include<stdio.h>
  • 新式headers內(nèi)的組件封裝于namespace "std"
    • using namespace std; or
    • using std::cout; (for example)
  • 舊式headers內(nèi)的組件不封裝于namespace "std"

幾個(gè)重要網(wǎng)頁

  • CPlusPlus.com -- The C++ Resources Network
  • CppReference.com -- C++ 參考手冊
  • gcc.gnu.org/onlinedocs -- GCC online documentation

書目志

  1. The C++ Standard Library - A Tutorial and Reference (2nd Edition) by Nicolai M. Josuttis
  2. STL源碼剖析 by 侯捷

STL六大部分

STL六大部件(Components):

  • 容器(Containers)
  • 分配器(Allocators)
  • 算法(Algorithm)
  • 迭代器(Iterators)
  • 適配器(Adapters)
  • 仿函式(Functors)

一個(gè)包含STL六大部件的程序

#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>

using namespace std;

int main()
{
  int ia[ 6 ] = { 27, 210, 12, 47, 109, 83 };
  vector<int, allocator<int>> vi(ia, ia+6);
  cout << count_if(vi.begin(), vi.end(), 
            not1(bind2nd(less<int>(), 40)));
  return 0;
}
stl-6-comp.png

復(fù)雜度, Complexity, Big O

目前常見的big O有下列幾種情形:

  1. O(1)或O(c): 稱為常數(shù)時(shí)間(constant time)
  2. O(n): 稱為線性時(shí)間(linear time)
  3. O(log2(n)): 稱為次線性時(shí)間(sub-linear time)
  4. O(n^2): 稱為平方時(shí)間(quadratic time)
  5. O(n^3): 稱為立方時(shí)間(cubic time)
  6. O(2^n): 稱為指數(shù)時(shí)間(exponential time)
  7. O(nlog2(n)): 介于線性及二次方成長的中間之行為模式

前閉后開

Container<T> c;
...
Container<T>::iterator ite;
for (ite = c.begin(); ite != c.end(); ++ite)
  ...

關(guān)于end()的一些解釋 (摘自C++ Primer):

The iterator returned by end is an iterator positioned “one past the end” of the associated container (or string). This iterator denotes a nonexistent element “off the end” of the container. It is used as a marker indicating when we have processed all the elements. The iterator returned by end is often referred to as the off-the-end iterator or abbreviated as “the end iterator.” If the container is empty, begin returns the same iterator as the one returned by end. If the container is empty, the iterators returned by begin and end are equal—they are both off-the-end iterators.

ranged-based for statement (since C++11)

摘自C++ Primer:

The new standard introduced a simpler for statement that can be used to iterate through the elements of a container or other sequence. The syntactic form of the range for statement is:
for (declaration : expression) { statement }
expression must represent a sequence, such as a braced initializer list, an array, or an object of a type such as vector or string that has begin and end members that return iterators. declaration defines a variable. It must be possible to convert each element of the sequence to the variable’s type. The easiest way to ensure that the types match is to use the auto type specifier. That way the compiler will deduce the type for us. If we want to write to the elements in the sequence, the loop variable must be a reference type. On each iteration, the control variable is defined and initialized by the next value in the sequence, after which statement is executed. As usual, statement can be a single statement or a block. Execution ends once all the elements have been processed.

例子:

for (int i : {2 , 3, 5, 7, 9, 13, 17, 19}) {
  std::cout << i << std::endl;
}
std::vector<double> vec;
...
// pass by value
for (auto elem : vec) {
  std::cout << elem << std::endl;
}
// pass by reference
for (auto &elem : vec) {
  elem *= 3;
}

auto keyword (since C++11)

摘自C++ Primer:

It is not uncommon to want to store the value of an expression in a variable. To declare the variable, we have to know the type of that expression. When we write a program, it can be surprisingly difficult—and sometimes even impossible—to determine the type of an expression. Under the new standard, we can let the compiler figure out the type for us by using the auto type specifier. Unlike type specifiers, such as double, that name a specific type, auto tells the compiler to deduce the type from the initializer. By implication, a variable that uses auto as its type specifier must have an initializer.

例子:
不使用auto:

list<string> c;
...
list<string>::iterator ite;
ite = ::find(c.begin(), c.end(), target);

使用auto:

list<string> c;
...
auto ite = ::find(c.begin(), c.end(), target);

容器--結(jié)構(gòu)與分類

container.png

評(píng)論: 容器主要分為Sequence container和Associative container兩大類, 而Associative container又可按照Elements Ordered/Not Ordered by Key分成兩類. 具體的容器的定義和討論可見以下兩個(gè)小節(jié).

Sequence Containers

摘自C++ Primer:

Sequential Container Description
vector Flexble-size array. Supports fast random access. Inserting or deleting elements other than at the back may be slow.
deque Double-ended queue. Supports fast random access. Fast insert/delete at front or back.
list Doubly linked list. Supports only bidirectional sequential access. Fast insert/delete at any point in the list.
forward_list Singly linked list. Supports only sequential access in one direction. Fast insert/delete at any point in the list.
array Fixed-size array. Supports fast random access. Cannot add or remove elements.
string A specialized container, similar to vector, that contains characters. Fast random access. Fast insert/delete at the back.

The sequential containers, which are listed in the Table, all provide fast sequential access to their elements. However, these containers offer different performance trade-offs relative to 1. The costs to add or delete elements to the container; 2. The costs to perform nonsequential access to elements of the container
With the exception of array, which is a fixed-size container, the containers provide efficient, flexible memory management. We can add and remove elements, growing and shrinking the size of the container. The strategies that the containers use for storing their elements have inherent, and sometimes significant, impact on the
efficiency of these operations. In some cases, these strategies also affect whether a particular container supplies a particular operation.
For example, string and vector hold their elements in contiguous memory. Because elements are contiguous, it is fast to compute the address of an element from its index. However, adding or removing elements in the middle of one of these containers takes time: All the elements after the one inserted or removed have to be moved to maintain contiguity. Moreover, adding an element can sometimes require that additional storage be allocated. In that case, every element must be moved into the new storage.
The list and forward_list containers are designed to make it fast to add or remove an element anywhere in the container. In exchange, these types do not support random access to elements: We can access an element only by iterating through the container. Moreover, the memory overhead for these containers is often
substantial, when compared to vector, deque, and array.
A deque is a more complicated data structure. Like string and vector, deque supports fast random access. As with string and vector, adding or removing elements in the middle of a deque is a (potentially) expensive operation. However, adding or removing elements at either end of the deque is a fast operation, comparable to adding an element to a list or forward_list.
The forward_list and array types were added by the new standard. An array is a safer, easier-to-use alternative to built-in arrays. Like built-in arrays, library arrays have fixed size. As a result, array does not support operations to add and remove elements or to resize the container. A forward_list is intended to be comparable to the best handwritten, singly linked list. Consequently, forward_list does not have the size operation because storing or computing its size would entail overhead compared to a handwritten list. For the other containers, size is guaranteed to be a fast, constant-time operation.

Associative Container

摘自C++ Primer:

Associative Container Description
Elements Ordered by Key
map Associative array; holds key-value pairs
set Container in which the key is the value
multimap map in which a key can appear multiple times
multiset set in which a key can appear multiple times
Unordered Collections
unordered_map map organized by a hash function
unordered_set set organized by a hash function
unordered_multimap Hashed map; keys can appear multiple times
unordered_multiset Hashed set; keys can appear multiple times

Associative and sequential containers differ from one another in a fundamental way: Elements in an associative container are stored and retrieved by a key. In contrast, elements in a sequential container are stored and accessed sequentially by their position in the container. Although the associative containers share much of the behavior of the sequential containers, they differ from the sequential containers in ways that reflect the use of keys.
Associative containers support efficient lookup and retrieval by a key. The two primary associative-container types are map and set. The elements in a map are key–value pairs: The key serves as an index into the map, and the value represents the data associated with that index. A set element contains only a key; a set supports efficient queries as to whether a given key is present. We might use a set to hold words that we want to ignore during some kind of text processing. A dictionary would be a good use for a map: The word would be the key, and its definition would be the value.
The library provides eight associative containers, listed in the Table. These eight differ along three dimensions: Each container is (1) a set or a map, (2) requires unique keys or allows multiple keys, and (3) stores the elements in order or not. The containers that allow multiple keys include the word multi; those that do not keep their keys ordered start with the word unordered. Hence an unordered_multiset is a set that allows multiple keys whose elements are not stored in order, whereas a set has unique keys that are stored in order. The unordered containers use a hash function to organize their elements.
The map and multimap types are defined in the map header; the set and multiset types are in the set header; and the unordered containers are in the unordered_map and unordered_set headers.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子旬渠,更是在濱河造成了極大的恐慌,老刑警劉巖岖免,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栅炒,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)玩讳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門樟澜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柔吼,“玉大人觅玻,你說我怎么就攤上這事◎蚪洌” “怎么了串塑?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長北苟。 經(jīng)常有香客問我桩匪,道長,這世上最難降的妖魔是什么友鼻? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任傻昙,我火速辦了婚禮闺骚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘妆档。我一直安慰自己僻爽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布贾惦。 她就那樣靜靜地躺著胸梆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪须板。 梳的紋絲不亂的頭發(fā)上碰镜,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音习瑰,去河邊找鬼绪颖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛甜奄,可吹牛的內(nèi)容都是我干的柠横。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼课兄,長吁一口氣:“原來是場噩夢啊……” “哼牍氛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起第喳,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤糜俗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后曲饱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悠抹,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年扩淀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了楔敌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驻谆,死狀恐怖卵凑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胜臊,我是刑警寧澤勺卢,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站象对,受9級(jí)特大地震影響黑忱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一甫煞、第九天 我趴在偏房一處隱蔽的房頂上張望菇曲。 院中可真熱鬧,春花似錦抚吠、人聲如沸常潮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喊式。三九已至,卻和暖如春弥雹,著一層夾襖步出監(jiān)牢的瞬間垃帅,已是汗流浹背延届。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工剪勿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人方庭。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓厕吉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親械念。 傳聞我的和親對象是個(gè)殘疾皇子头朱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,441評(píng)論 5 6
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,429評(píng)論 0 23
  • 【歌羅西書1:9-14】 因此,我們自從聽見的日子龄减,也就為你們不住地禱告祈求项钮,愿你們在一切屬靈的智慧悟性上,滿心知...
    媚子_亮光的故事閱讀 2,364評(píng)論 0 1
  • 我有一個(gè)朋友小雪,是個(gè)很暖的人宠能。 她把別人的事亚隙,都當(dāng)成了自己的事,總覺得對別人好了违崇,別人也會(huì)對她好阿弃。 小雪剛工作那...
    沉濁閱讀 271評(píng)論 0 0
  • 6-9號(hào)出差,公司在北京舉行了一個(gè)非常有逼格的大會(huì)羞延,為了這個(gè)會(huì)渣淳,我忙的清明加了三天班,感覺身體被掏空伴箩,5入愧,6,7,...
    小二關(guān)閱讀 115評(píng)論 0 0