1,标准库定义了3种类型的顺序容器:vector、list和deque。它们的差别主要在于访问元素的方式,以及添加或删除元素相关操作运算代价。标准库还提供了三种容器适配器:stac
第9章 顺序容器
1,标准库定义了3种类型的顺序容器:vector、list和deque。它们的差别主要在于访问元素的方式,以及添加或删除元素相关操作运算代价。标准库还提供了三种容器适配器:stack、queue和priority_queue。
2,将一个容器复制给另一个容器时,类型必须匹配,包括容器类型和元素类型。
vector<int> ivec;
vector<double> dvec(ivec); //error
list<int> ilist(ivec); // error
3,可以用一对指针或一对迭代器,把它们之间的值复制给容器,可以允许类型不一致。
vector<string> svec;
list<string> slist(svec.begin(),svec.end());
vector<string>::iterator mid = svec.begin() + svec.size() / 2;
deque<string> front(svec.begin(),mid); // 不包括 *mid
// 用指针初始化
char* word[] = {"monday","tuesday","wesday"};
size_t words_size = sizeof(word) / sizeof(char*);
list<string> words2(word, word + words_size);
4,注意除了引用外,所有内置或复合类型都可以做容器的元素类型。引用不支持一般意义的赋值操作。除输入输出标准库类型(以及auto_ptr)外,所有其他标准库类型都是有效的容器元素类型。
5,list容器的迭代器不支持算术运算,也不支持关系运算。因为list里的元素,没有序号或位置这个概念。
6,所有相同类型的容器都支持关系操作符来实现两个容器的比较:
1)如果两个容器具有相同的长度而且所有元素都相等,那么两个两个容器相等;否则,就不相等。
2)如果两个容器的长度不相同,但较短的容器中所有元素都等于较长容器中对应的元素,则称较短的容器小于另一容器。
3)如果两个容器都不是对方的初始子序列,则它们的比较结果取决于所比较的第一个不相等的元素。
如果容器内的元素不支持比较大小,则容器就不能比较大小。
7,获得容器元素的引用,有两种方法:1)front与back成员函数;2)迭代器解引用。
list<int> ilist;
if (!ilist.empty())
{
list<int>::reference val = ilist.front();
list<int>::reference val1 = *ilist.begin();
list<int>::reference last = ilist.back();
list<int>::reference last1 = *--ilist.end();
}
return 0;
注意取引用时,一定要保证ilist非空。
8,在使用erase删除容器内两个迭代器之间的元素时,erase(elem1,elem2),这里删除的元素不包括elem2。
9,容器的赋值,顺序容器有几下几种赋值操作:
1)c1=c2:删除c1的所有元素,然后将c2的元素复制给c1,c1和c2的类型(容器类型与元素类型)必须相同。
2)c1.swap(c2):顾名思义,交换c1与c2的值,实际上这个操作,只是交换了彼此的地址。交换后c1批向了原来c2的指针内容。
3)c.assign(b,e):重新设置c的元素,将迭代器b与e之间的所有元素复制到c中,当然b与e不能是c的的迭代器。
4)c.assign(n,t):将容器c重新设置为存储n个值为t的元素。
注意assign操作允许发生类型转换。可以将char*元素assign给存储string的容器。swap是速度最快的,没有删除元素的成本。
10,一般意义下vector的元素是按顺序存储的,这就造成了,如果插入元素,则库将进行重新内存分配,并涉及到的旧vector的销毁。而实际中vector容器预留了这些额外的存储区用于存放新添加的元素。因此在实际上,比起list与deqeue容器,vector的增长效率通常会更高。
11,vector容器实际空间可能会比元素所占的空间更大,capacity成员函数用于返回容器实际的容量大小,一般比size要大。如果一直往vector内插入元素,则直到size==capacity之间,vector都不用重新进行内存分配。但如果再往里插入元素时,将又会重新分配,capacity又会比size大。
第10章 关联容器
1,pair类型:
pair<string, string> name("ronny", "young"); // 定义并初始化
name = make_pair("ronny", "young");
string fullName = name.first + name.second;
2,关联容器
1)关联容器map实际上是装有n个pair类型的集合。map定义了三个类型别名,key_type、mapped_type、value_type分别表示键的类型、键所关联的值的类型和map里pair类型。
2)当使用下标访问map的值时,如果下标不存在,则导致在map中新添一个新的元素,它的键即为该下标值。
3)map的迭代器指向的是pair类型,所以当对迭代器解引用时,得到的是一个pair类型。这与下标得到的类型不同。
4)统计单词出现次数的例子:
map<string, int> word_cnt;
string word;
while (cin >> word)
{
++word_cnt[word];
}
5)利用insert返回的类型来重写上面的程序,insert返回了一个pair类型,它的first成员为一个迭代器,而second成员为一个bool变量,表明该元素是否被插入。
map<string, int> word_cnt;
string word;
while (cin >> word)
{
pair