C++标准库学习笔记-5-(Container)

来源:互联网 发布:淘宝飞鱼运动是正品么 编辑:程序博客网 时间:2024/06/05 06:46

声明:这个博文所有内容均来自于C++标准库-自学教程与参考手册(第二版)英文版 上册。如果转载,务必附带本声明,并注明出处。 
STL为了满足不同需求而创造了一些列通用的容器 
Contianer
这里写图片描述
这里写图片描述
**

一、Containers

** 
1、Vector 
使用vector需要添加头文件< vector>,vector也包含在std namespace. 
vector的所有函数可以在这里查到。 
这里在啰嗦下常用的几个函数。 
begin()、end()、front()、back():前两个用于获取第一个和最后一个迭代器的,后两个是用于获取第一个和最后一个元素的。 
push_back()、pop_back():添加、删除最后一个元素。 
resize()重置vector大小,同时可以指定重置后的值。不过这种重置是只取前面的n个元素。 
[]、at(),用于索引。 
data(),返回vector中用户存储数据的首地址。 
vector的使用相当简单,使用也广泛。不过如果数据管理简单,而且数据个数不变动的,建议直接使用数组以获得更高的效率。

2、Deque 
deque是“double-ended queue”的缩写,是一种可以在两端伸长或缩短的双向数组。所以在两端插入数据是非常快的,但是在中间插入会很慢,因为部分元素需要移动位置。Deque就是比vector多了个双向的性质。

#include <iostream>#include <vector>#include <deque>int main(){    std::vector<int> vInt;    vInt.push_back(5201314);    std::deque<double> dqDouble;    for (int i = 0; i < 8; ++i)    {        if (i % 2 == 0)            dqDouble.push_back(i * 1.0);        else        {            dqDouble.push_front( i * 1.0 );        }    }    for (auto iter : dqDouble)        std::cout << iter << "  ";    std::cout << std::endl;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3、Array 
Array是STL提供的用于管理固定大小的容器。因此在使用时,它的大小是不能改变的。这个和普通的数组差不多,无法动态分配。同时C++11的Array也不支持多维数组。感觉用处不是很大。

4、List 
在C++11里面有两种链表,一种就是list<>,它是一种双向链表,还有一种是forward_list; 
使用List的好处就在于插入或者删除元素所占用的时间是很短的,因为它仅需要改变指针,而不用移动元素。但是List不支持random access(可以翻译为随机获取吗?),也就是说它无法通过索引来获取元素,只能从第一个一直往下推导。这样做的问题在于:当链表很长时,如果想获取最后一个元素也许要消耗较长时间。forward_list让链表只能朝着一个方向生长,其他方面与list<>类似。

int main(){    std::list<char> cList;    for (char c = 'a'; c <= 'z'; ++c)        cList.push_back(c);    for (auto &elem : cList)        std::cout << elem << ' ';    std::cout << std::endl;    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

二、Associative Containers

Associative containers会根据特定的排序规则自动将元素排序,元素可能是任意类型或者是pair的。默认情况下,它会通过运算符 “<”来对普通value(或者pair里面的key 或value)来排序。但用户也可以自定义排序规则。

Associative containers 典型的实现就是二叉树。每个元素都只有一个父节点和两个子节点(或者没有子节点)。它的主要好处在于查找快速。

这里写图片描述
所有的Associative containers 都有一个可选的模板参数用于排序。

int main(){    std::multiset<std::string> cities{    "Braunschweig", "Hanover", "Frankfurt", "New York",    "Chicago", "Toronto", "Paris", "Frankfurt"};    // print each element:    for (const auto& elem : cities) {        std::cout << elem.data() << " ";//本来书上是直接 std::cout << elem << " " ;但是VS2013报错了,我改了之后可以正常运行。    }    std::cout << std::endl;    // insert additional values:    cities.insert({ "London", "Munich", "Hanover", "Braunschweig" });    // print each element:    for (const auto& elem : cities) {        std::cout << elem.data() << " ";    }    std::cout << std::endl;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

输出结果为: 
Braunschweig Chicago Frankfurt Frankfurt Hanover New York Paris Toronto 
Braunschweig Braunschweig Chicago Frankfurt Frankfurt Hanover Hanover London Munich New York Paris Toronto 
请按任意键继续…

下面是一个关于multimap的例子:

int main(){    multimap<int, string> coll = { { 5, "tagged" },    { 2, "a" },    { 1, "this" },    { 4, "of" },    { 6, "strings" },    { 1, "is" },    { 3, "multimap" } };     //这里书本上是    /*multimap<int, string> coll; // container for int/string values    // insert some elements in arbitrary order    // - a value with key 1 gets inserted twice    coll = { { 5, "tagged" },    { 2, "a" },    { 1, "this" },    { 4, "of" },    { 6, "strings" },    { 1, "is" },    { 3, "multimap" } };*/ //但是运行报错,不能这样初始化。cpp reference给出的使用make_pair方式    // print all element values    // - element member second is the value    for (auto elem : coll) {        cout << elem.second.data() << endl; //这里书本中是直接使用elem.second来输出,但是VS2013报错    }    cout << endl;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

三、Unordered Containers

unordered containers,顾名思义,里面的元素是没有特定排序的。它就像一个袋子一样,只是装东西,但是这个东西在这个袋子的哪个地方是无法预先知道的。如果有两个一样的这样的容器,就算你放入数据一样,最后得到的顺序还是有可能不一样。unordered containers典型的实现就是哈希表。在内部,这种容器是一系列的链表。通过使用哈希函数,元素的位置就可以得到处理。设计这种容器的目的就在于让你能够快速获取元素,因为有哈希表。 
这里写图片描述
具体类型有: 
• An unordered set is a collection of unordered elements, where each element may occur only 
once. Thus, duplicates are not allowed. 
• An unordered multiset is the same as an unordered set except that duplicates are allowed. Thus, 
an unordered multiset may contain multiple elements that have the same value. 
• An unordered map contains elements that are key/value pairs. Each key may occur only once, 
so duplicate keys are not allowed. An unordered map can also be used as an associative array, 
an array that has an arbitrary index type (see Section 6.2.4, page 185, for details). 
• An unordered multimap is the same as an unordered map except that duplicates are allowed. 
Thus, an unordered multimap may contain multiple elements that have the same key. An unordered multimap can also be used as dictionary (see Section 7.9.7, page 383, for an example).

int main(){    //需要包含头文件<unordered_set>    unordered_multiset<string> cities{    "Braunschweig", "Hanover", "Frankfurt", "New York",    "Chicago", "Toronto", "Paris", "Frankfurt"};    // print each element:    for (const auto& elem : cities) {        cout << elem.data() << " ";    }    cout << endl;    // insert additional values:    cities.insert({ "London", "Munich", "Hanover", "Braunschweig" });    // print each element:    for (const auto& elem : cities) {        cout << elem.data() << " ";    }    cout << endl;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

再来一个unordered_map的例子:

int main(){    //需要#include <unordered_map>    unordered_map<string, double> coll{ { "tim", 9.9 },    { "struppi", 11.77 }};    // square the value of each element:    for (pair<const string, double>& elem : coll) {        elem.second *= elem.second;    }    // print each element (key and value):    for (const auto& elem : coll) {        cout << elem.first.data() << ": " << elem.second << endl;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

四、Associative Arrays

直接先上代码吧:

int main(){    unordered_map<string, double> coll;    coll["A"] = 0.1;    coll["B"] = 0.2;    coll["Pi"] = 3.1415926;    coll["money"] = -99.9;    for (auto iter : coll)        cout << iter.first.data() << ":" << iter.second << endl;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这段代码像极了python的字典。这里的 [] 运算符用于提取map里面的pair里面的第一个元素,如果这个元素存在,那个就直接赋值了,如果不存在,那么就添加后赋值。