C++标准模板库笔记
C++标准模板库笔记(C++ Primer plus)
1.除序列外,vector还是可反转容器(reversible container)概念的模型。
它有两个类方法:rbegin()和rend(),前者返回一个指向反转序列的第
一个元素的迭代器,后者返回反转序列的超尾迭代器。这些迭代
器都是reverse_iterator,对这样的迭代器执行递增操作,将导致它
反向遍历可反转容器。
如果dice是一个vector容器,而Show(int)是显示一个整数的函数,
则:
for_each(dice.begin(),dice.end(),Show); //正向显示dice的内容for_each(dice.rbegin(),dice.rend(),Show); //反向显示dice的内容
vector模板类是最简单的序列模型,除非其他类型的特殊有点能够更好地满足程序的要求,否则应该默认使用这种类型。
2.deque模板类(在deque头文件中声明)表示双端队列(double-ended queue),通常被简称为deque。
在STL中,其实现类似于vector容器,支持随机访问。其主要区别
在于,从deque对象的开始位置插入和删除元素的时间是固定的,
而不像vector中那样是线性时间的。
虽然vector和deque都提供对元素的随机访问和在序列中部执行线
性时间的插入和删除操作,但vector容器执行这些操作时速度要快些。
3.list模板类(在list头文件中声明)表示双向链表。
区别:list在链表中任一位置进行插入和删除的时间都是固定的,
因此,vector强调的是通过随机访问进行快速访问,而list强调的
是元素的快速插入和删除。
与vector相似,list也是可反转容器。不同的是,list不支持数组表
示法和随机访问,从容器中插入或删除元素之后,链表迭代器指
向元素将不变。(只是修改连接信息,指向某个元素的迭代器仍
然指向该元素。)
list 模板包含了链表专用的成员函数:
insert()和splice()之间的主要区别在于:insert()将原始区间的副本插入到目标地址,而splice()则将原始区间移到目标地址。移动后,被移动的容器将置空(splice()方法还有其他原型,用于移动单个元素和元素区间)。原始容器的迭代器将重新定位到新容器,迭代器仍然指向相同的元素。
1.void splice ( iterator position, list<T,Allocator>& x );2.void splice ( iterator position, list<T,Allocator>& x, iterator it );3.void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last );position 是要操作的list对象的迭代器1:会在position后把list&x所有的元素到剪接到要操作的list对象
2:只会把it的值剪接到要操作的list对象中
3:把first 到 last 剪接到要操作的list对象中
unique()只能将相邻的相同值压缩为单个值,但使用sort()后,再
使用unique()时,每个值将只占一个位置。
对于 非成员sort()函数,它需要随机访问迭代器,因为快速插入的
代价是放弃随机访问功能,所以不能将非成员函数sort()用于链表。
因此,list容器中包括了一个只能在类中使用的成员版本。
4.C++11新增了容器类forward_list,它实现了单链表。在这种链表
中,每个节点都只链接到下一个节点。因此,forward_list只需要
正向迭代器,是不可反转容器。相比于list,forward_list更简单,更
紧凑,但功能也更少。
5.queue模板类是一个适配器类
ostream_iterator模板也是一个适配器,让输出流能够使用迭代器
接口。queue模板让底层类(默认为deque)展示典型的队列接口。
queue模板的限制比deque更多,它不仅不允许随机访问队列元
素,甚至不允许遍历队列。
6.priority_queue模板类(在queue头文件中声明)是另一个适配
器类,它支持的操作与queue相同。两者的主要区别在于:在
priority_queue中,比重最大的元素被移到队首,内部区别在于,
默认的底层类是vector。
它可以修改用于确定哪个元素被放到队首的比较方式
7.stack 与queue相似,stack也是一个适配器类,它给底层类(默
认是vector)提供了典型的栈接口
stack模板的限制比vector更多,它不仅不允许随机访问栈元素,
甚至不允许遍历栈。
8.array 模板类array在头文件array中定义,它不是STL容器,因为
其长度是固定的。像push_back(),insert()这种调整容器大小的操
作,array都没有,但是它有operator和at()。可将很多标准STL算
法用于array对象,如copy()和for_each()。
9.关联容器(associative container) 将值与键关联在一起,并用
键来查找值。
关联容器的优点在于,它提供了对元素的快速访问。关联容器允
许插入新元素,但不能指定元素的插入位置。原因是关联容器通
常有用于确定数据放置位置的算法,以便能快速检索信息。
关联容器通常是使用某种树实现的。像链表一样,树的节点使得
添加或删除数据项比较简单。但相对于链表,树的查找速度更
快。
STL提供了四种关联容器:set, multiset, map, 和multimap
(set和map头文件)
最简单的关联容器是set,其值和键的类型相同,键是唯一的。
multiset类似于set,只是可能有多个值的键相同。
map中 值与键的类型不同,键是唯一的。但是multimap中一个键
可以对应多个值。
10.无序关联容器 与关联容器一样,也将值与键关联起来,并使用
键来查找值。但底层的差别在于,关联容器是基于树结构的,而
无序关联容器是基于哈希表的,目的是提高元素的添加和删除速
度以及提高查找算法的效率。
11.函数对象: 很多STL算法都使用函数对象——也叫函数符
(functor)。函数符是可以以函数方式与()结合使用的任意对象。这
包括函数名,指向函数的指针和重载了()运算符的类对象。
12.对于所有内置的算术运算符,关系运算符和逻辑运算符,STL
都提供了等价的函数符。
13. STL算法有两个主要的通用部分。首先,它们都使用模板来提
供泛型;其次它们都使用迭代器来提供访问容器中数据的通用表
示。
STL将算法库分成4种:
- 非修改式序列操作(find(),for_each()…)
- 修改式序列操作(transform(),random_shuffle(),copy()…)
- 排序和相关操作(sort(),其它集合操作等等)
- 通用数字运算(比如将区间的内容累积,计算两个容器的内部乘积)
前3组在头文件algorithm中,第4组在numeric中。
有些算法有两个版本:就地版本和复制版本。STL的约定是,复
制版本的名称将以_copy结尾。复制版本将接受一个额外的输出迭
代器参数,该参数指定结果的放置位置。如:void replace_copy(…)
有些函数有这样的版本,即根据将函数应用于容器元素得到的结果
来执行操作。这些版本的名称通常以_if结尾。如:void replace_if(…)
14.string类虽然不是STL的组成部分,但设计它时考虑到了STL,
因此可以使用STL接口。
next_permutation()算法将区间内容转换为下一种排列方式。对于
字符串,排列按照字母递增的顺序进行。如果成功则返回true,
如果区间已经处于最后的序列中,则返回false。比如:
string letters;
...
sort(letters.begin(),letters.end());
while(next_permutation(letters.begin(),letters.end())
cout<<letters<<endl;
这个将输出字符串的所有排列。
15.有时可以选择使用STL方法或STL函数。通常 方法 是更好的选
择。首先,它更适合于特定的容器;其次,作为成员函数,它可
以使用模板类的内存管理工具,从而在需要时调整容器的长度。
而函数,它不是成员,并不能调整容器的长度。(不过可以让函
数的返回值是指向新的超尾值的迭代器,来提醒容器长度改变了)
16.编写一个程序,让用户输入单词。希望最后得到一个按输入顺
序排列的单词列表、一个按字母顺序排列的单词列表(忽略大小写)
,并记录每个单词被输入的次数。
//set会自动对元素进行排序,并且不会有相同元素出现。
#include<iostream>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<iterator>
#include<algorithm>
using namespace std;char toLower(char ch) { return tolower(ch); }
string& ToLower(string& st);
void display(const string& s);int main()
{vector<string>words;cout << "Enter words (enter quit to quit):" << endl;string input;while (cin >> input && input != "quit") {words.push_back(input);}cout << "You entered the following words:" << endl;for_each(words.begin(), words.end(), display);cout << endl;set<string>wordset;transform(words.begin(), words.end(), insert_iterator<set<string>>(wordset, wordset.begin()), ToLower);cout << endl << "Alphabetic list of words:" << endl;for_each(wordset.begin(), wordset.end(), display);cout << endl;map<string, int>wordmap;set<string>::iterator si;for (si = wordset.begin(); si != wordset.end(); ++si)wordmap[*si] = count(words.begin(), words.end(), *si);cout << endl << "Word frequency:" << endl;for (si = wordset.begin(); si != wordset.end(); ++si)cout << *si << ": " << wordmap[*si] << endl;return 0;
}string& ToLower(string& st)
{transform(st.begin(), st.end(), st.begin(), toLower);return st;
}void display(const string& s)
{cout << s << " ";
}
C++提供三个数组模板:vector、valarray和array。
vector模板类支持面向容器的操作,
valarray是面向数值计算的,不是STL的一部分,
array是为替代内置数组而设计的。
若将两个数组各个元素相加,并将和存储到新的的对象中:
vector< double > ved1(10),ved2(10),ved3(10);
array <double,10>vod1,vod2,vod3;
valarray< double >vad1(10),vad2(10),vad3(10);
对于vector类:
transform(ved1.begin(),ved1.end(),ved2.begin(),ved3.begin(),plus< double >());
对于array类:
transform(vod1.begin(),vod1.end(),vod2.begin(),vod3.begin(),plus< double >());
对于valarray类:
vad3=vad1+vad2; //因为valarray类重载了所有算术运算符。
显然,执行多步运算时,valarray接口的简单性更加明显。
17.initializer_list
使用initializer_list对象,必须包含头文件initializer_list。这个模板
类包含成员函数begin()和end(),可以使用这两个函数来访问列表
元素。它还包含成员函数size(),返回元素数。
可按值或者按引用传递initializer_list对象。这种对象本身很小,通
常是两个指针(一个指向开头,一个指向末尾的下一个元素),
也可能是一个指针和一个表示元素数的整数,所以传递方式对性
能的影响不大。
initializer_list的迭代器类型为const。
initializer_list类的初衷是将一系列值传递给构造函数或其他函数。
18.STL是一个容器类模板,迭代器模板,函数对象模板和算法模
板的集合,它们的设计都是基于泛型编程原则。算法通过使用模
板,从而独立于所存储的对象的类型;通过使用迭代器接口,从
而独立于容器的类型。
19.智能指针
智能指针模板(auto_ptr,unique_ptr和shared_ptr)(头文件
memory)都定义了类似指针的对象,可以将new获得(直接或间
接)的地址赋给这种对象。当智能指针过期时,其析构函数将使
用delete来释放内存。
所有智能指针类都有一个explicit构造函数,该构造函数将指针作
为参数。
三种智能指针都应该避免的一点:
double a=1.0;
shared_ptr<double> pa(&a); //NO!
//因为这样会导致delete运算符用于非堆内存。
为了避免删除同一个对象2次,可以用下面这些方法:
- 重载赋值运算符,使之执行深复制
- 建立所有权(ownership)概念,对于特定的对象,只能有一个智能指针拥有它,然后让赋值操作转让所有权。(这种方法的缺点是当指针丧失所有权后,若我们继续用这个指针去访问对象,会引发异常,因为丧失所有权后的智能指针是空指针。)
- 引用计数(reference counting),跟踪引用特定对象的智能指针数。 比如赋值时,计数加1,指针过期时,计数减1,当最后一个指针过期时,调用delete。
unique_ptr和auto_ptr都是用建立所有权的办法,但是unique_ptr比auto_ptr更严谨,不容易引发异常。假如程序试图将一个unique_ptr赋给另一个时,如果源unique_ptr是个临时右值(比如返回值是非引用变量),编译器不会报错,但是如果源unique_ptr将存在一段时间,编译器会报错。
20.相比于auto_ptr,unique_ptr还有另一个优点:
因为delete和new配对,delete[]和new[]配对。而模板auto_ptr使用delete而不是delete[],因此只能与new一起使用,而不能与new[]一起使用。但unique_ptr可以(shared_ptr也不可以):
std::unique_ptr<double[]>pda(new double(5))
21.注意下面show函数里面的参数
C++标准模板库笔记相关推荐
- C++标准库学习笔记——标准模板库笔记
目录 1. STL组件 2. 容器 2.1 容器分类 2.2 三种容器实现原理 2.3 关联式和无序容器的小知识点 2.4 容器适配器 3. 迭代器 3.1 迭代器概念与基本操作 3.2 迭代器的半开 ...
- C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)
C++ 标准库可以分为两部分: 标准函数库: 这个库是由通用的.独立的.不属于任何类的函数组成的.函数库继承自 C 语言. 面向对象类库: 这个库是类及其相关函数的集合. C++ 标准库包含了所有的 ...
- 提高C++性能的编程技术笔记:标准模板库+测试代码
标准模板库(Standard Template Library, STL)是容器和通用算法的强效组合. 渐近复杂度:算法的渐近复杂度是对算法性能的近似估计.它是算法集到特定性能标准集的映射.如果需要对 ...
- 《C++ Primer Plus》读书笔记 第16章 string类和标准模板库
第16章 string类和标准模板库 1.string类 表16.1列出了string类的几个构造函数.其中NBTS(null-terminated string)表示以空字符结束的传统C-风格字符串 ...
- 《C++ Primer Plus》学习笔记-string类和标准模板库
第16章 string类和标准模板库(本书附录G有详细介绍) 16.1 string类 string类是由头文件string支持的. string类位于命名空间std中. ctor标识是传统C++中构 ...
- C++Primer Plus笔记——第十六章 string类和标准模板库总结及程序清单
目录 本章小结 程序清单 string类 16.1 str1.cpp 16.2 strfile.cpp 16.3 hangman.cpp ...
- C++ Primer plus学习笔记-第十六章:string类和标准模板库
第十六章:string类和标准模板库 前言:这一章已经相当靠近全书的后面部分了:这一章我们会深入探讨一些技术上的细节,比如string的具体构造函数,比如适用于string类的几个函数,比如我们还会介 ...
- C++标准模板库(STL)笔记与示例
C++标准模板库知识点: /*一.主要内容: sort //必会! next_permutation() //记住怎么调用 list // stack //调用类库 queue //调用类库 vect ...
- C++ Primer Plus 笔记(16章:string类和标准模板库)
16 string类和标准模板库 16.1 string类 16.1.1 构造字符串 常见的字符串书中给了7个,另外还有两个在C++11里新增的(NTBS)表示以空字符结束的传统字符串 构造函数 描述 ...
最新文章
- Mac 从Makefile 编译 Rocksdb 源码的一些注意事项
- Spark Operator资料收集
- grep线上环境精典案例后续
- Java多线程中使用ReentrantLock、synchronized加锁 简单举例
- jq处理返回来json_4个小窍门,让你在Python中高效使用JSON
- 盘点数据科学最流行的29个Python库
- 生产环境Go程序内存泄露,用pprof如何快速定位
- Tensorflow保存神经网络参数有妙招:Saver和Restore
- table 的 id 属性不被 document.getElementById支持
- Bootstrap面包屑导航
- [转]训练集和测试集的含义和区别?
- oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)
- 常用的做网站软件、网站制作软件分享
- 64位计算机安装xp,练习u盘如何安装XP 64位系统
- 网吧会员管理系统c语言,常用的网吧会员管理系统哪个比较好|纳客软件
- 依行科技日常实习面经
- 图解python中的time、datetime模块及他们的时间格式转换(附:格林尼治时间gmt、本地时间、协调世界时utc)
- .net 4.0 ValidateRequest=false 无效解决方法
- MACOS Terminal终端:更改zsh模式到bash模式(切换shell)
- Android通过NTRIP协议获取差分数据实现高精度定位