前段时间内看过C++primer,在新浪博客做了一下笔记,笔记写的很简陋,今天又重温了一下,由于平时都在用,而且这段时间比较忙,就不打算系统的整理,只是将以前的笔记复制过来,可能以前的理解错误较多,以后有时间系统在总结一下。
第九章
,在容器复制时,元素类型一定要一致。可以用迭代器来一个一个复制,只要他们兼容。如果元素类型没有默认构造函数,则必须显示的制定元素的初始化。访问容器时,不能越界。
三种容器均支持resieze()操作,重新划定容器大小,且此函数有重载。
vector
vector和built-in数组类似,是一个在堆上建立的一维数组,它拥有一段连续的内存空间,并且起始地址不变,因此 它能非常好的支持随即存取,即[]操作符。vector因为存储在堆上,所以支持erase( ), resieze()(重新划分容器容量)等操作; vector不用担心越界当空间不够用的时候,系统会自动按照一定的比例(对capacity( )大小)进行扩充。在vector序列末尾添加(push_back( ))或者删除(pop_back( ))对象效率高,在中间进行插入或删除效率很低,主要是要进行元素的移动和内存的拷贝,原因就在于当内存不够用的时候要执行重新分配内存,拷贝对象到新存储区,销毁old对象,释放内存等操 作,如果对象很多的话,这种操作代价是相当高的。为了减少这种代价,使用vector最理想的情况就是事先知道所要装入的对象数目,用成员函式 reserve( )预定下来;vector最大的优点莫过于是检索(用operator[ ])速度在这三个容器中是最快的,
list
list的本质是一个双向链表(根据sgi stl源代码),内存空间不连续,通过指针进行操作。说道链表,它的高效率首先表现是插入,删除元素,进行排序等等需要移动大量元素的操作。显然链表没有检索操作operator[ ], 也就是说不能对链表进行随机访问,而只能从头至尾地遍历,这是它的一个缺陷。list有不同于前两者的某些成员方法,如合并list的方法splice( ), 排序sort( ),交换list 的方法swap( )等等。
deque
deque是一个double-ended queue是由多个连续内存块构成,deque是list和vector的兼容,分为多个块,每一个块大小是512字节,块通过map块管理,map块里保存每个块得首地址。因此该容器也有索引操作operator[ ],效率没vector高。另外,deque比vector多了push_front( ) & pop_front( )操作。在两端进行此操作时与list的效率 差不多。
下面是选择顺序容器类型的一些准则
1.如果我们需要随机访问一个容器则vector要比list好得多 。
2.如果我们已知要存储元素的个数则vector 又是一个比list好的选择。
3.如果我们需要的不只是在容器两端插入和删除元素则list显然要比vector好
4.除非我们需要在容器首部插入和删除元素否则vector要比deque好。
5.如果只在容易的首部和尾部插入数据元素,则选择deque.
6.如果只需要在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑输入时将元素读入到一个List容器,接着对此容器重新排序,使其适合顺序访问,然后将排序后的list容器复制到一个vector容器中
6 再谈string
string 我把它理解成一个针对字符的vector,因为字符串的特殊,所以特地做出这样的一个东西来。
std::string是会在元素后面加上一个我们看不见的元素'\0'.
std::string不支持push_back()
std::vector没有对cout重载
第十章 关联容器
关联容器和顺序容器的差别是:关联容器通过剑(key)来存储和读取元素,而顺序容器则是按容器中的顺序和位置来读取操作。关联容器的行为大多和顺序容器的行为相同,只是多了一个Key的支持。
本章的关联容器有map(关联数组),set(可变大小的集合),multiset和multimap,这两个的一个key可以对应多个set和map.
1.标准库pair类型
pair也是标准库的一个类模板,头文件utility在里面。pair P;有其对应的first,和second来访问第一个或第二个,make_pair(first,second)返回一个pair对象。这个类型理解就行了不多讲。
2. 关联容器
关联容器支持大部分的顺序容器的操作,除了front,back,及对应的pop_和push_操作。
关联容器不能通过容器大小来定义,因为这样就无法知道键对应的只是什么,它的排列顺序是按键的次序来排列的,可以按键的顺序来访问。
对比list(适合无序的中间随机插入),vector(适合随机访问),deque(适合队列的首尾删除的操作),map(适合键-值对应的操作,如字典),set(合适一个集合操作,如黑名单)。
3.map类型
<span style="font-family:SimSun;"> map<string,int> word_count;
word_count["A"] = 1;</span>
会发生将键为A对应的值赋值为1,但如果没有键A,则会插入这个键并赋值为1,同样查找时 int count=word_count["A"],也会在没有A时添加键,并把值初始化为零。为了避免这种情况,利用word_count.count("A")和word_count.find("A"),来查找元素A出现的次数。例如:
<span style="font-family:SimSun;"> int occurs = 0;
map<string, int> word_count;
map<string,int>::iterator it = word_count.find("A");
if (it != word_count.end()) //如果A不存在,则find函数返回end迭代器,所以这么判断。
occurs = it->second;</span>
<span style="font-family:SimSun;"> string word;
map<string, int> word_count;
while (std::cin >> word)
{
++word_count[word]; //键word对应的值增加1.
}</span>
4.set类型
<span style="font-family:SimSun;"> vector<int> ivec(10);
set<int> iset(ivec.begin(), ivec.end());</span>
插入操作和insert(key),删除erase(key)。 set没有下标操作,判断有无用成员函数 iset.find(22);和iset.count(22)。set的迭代器解引用返回的是键。
5 multimap和multiset
6 容器的综合运动用(有时间一定要编写一下)
第十二章 泛型算法
发现一篇博文写的很详细:http://www.cnblogs.com/ForFreeDom/archive/2012/05/08/2489689.html。