2、输出运算符<<,作用于ostream类型的对象;cout是标准输出流,cerr是报告错误的标准流。默认情况下,写到cout的值被转换为一个字符序列。
3、>>输入运算符,其右侧运算对象决定输入声明类型的值和存储在哪里;cin标准输入流;
4、getline()读取一整行(包括结束的换行)
5、vector初始化,可在一对圆括号显式给出大小,默认元素被初始化为其类型默认值(指针为nullptr,整数为0),否则可以在构造函数第二个实参指定。
6、当拷贝非必要(vector数量很多时,这种赋值或初始化的拷贝会很耗时),优先使用指针或引用或移动操作。
7、标准库list,双向链表,支持添加和删除元素的同时无须移动其他元素。
8、当数据量较小时,vector性能会优于list,只是一个元素序列,二者皆可。除非具有充分理由选list,否则应用vector。vector无论遍历(find()和count())性能还是排序和搜索(sort()和binary_search())性能都优于list。
9、map用平衡二叉树实现。搜索map的代价是 O ( log ( n ) ) \mathcal{O}(\log(n)) O(log(n)), n n n是map元素的数目。
10、标准库哈希容器被称为“无序”容器,因为他们不需要序函数。(unordered_map),无序容器堆关键字(通常是字符串)搜索做了优化,这是采用哈希表实现的。
11、标准库提供容器适配器,queue<T>
,stack<T>
,deque<T>
,priority_queue<T>
,还提供更特殊的类似容器的类型,定长数组array<T,N>
和bitset<T>
12、推荐vector作为存储元素序列默认类型。
13、复制,写入内容会覆盖起始位置之后的元素。
unique_copy(vec.begin(),vec.end(),lst.begin());
复制不覆盖而是追加其后。
unique_copy(vec.begin(),vec.end(),back_inserter(res));
back_insert可以在追加过程中扩展容器空间容纳新元素。
14、任何一种特定的迭代器都是某种类型的对象。vector迭代器可以是普通指针,或指向vector存储空间起始位置的指针加上一个索引。list迭代器应该是指向某个链接。
15、流迭代器:输入流产生值序列,将之写入流。
创建otstream_iterator,指出使用的哪个流和输出对象类型。
otstream_iterator<string> oo{cout};
向*oo赋值左右是把所赋的值输出到cout中。
*oo = "hello,";//等价于cout<<"hello,";
++oo;//类似用指针向数组写入值
*oo = "world!\n";//等价于cout<<"world!\n";
isstream_iterator允许将输入流当做只读容器。需要指明哪个流读取数据以及数据类型。
isstream_iterator<string> ii{cout};
用一对输入迭代器表示一个序列,必须提供表示输入结束的isstream_iterator。
默认的isstream_iterator即可。
isstream_iterator<string> eos{};
16、查找满足特定要求元素的问题的更通用的方法,称为谓词(predicate)。
例在map中查询第一个大于42的值。访问map元素时,实际访问的是(关键字,值)对的序列。因此可将任务转化为在 map<string,int>
中搜索特定的 pair<const string,int>
,并要求int部分大于42。
auto p = find_if(m.begin(),m.end(),Greater_than{42});
Greater_than是函数对象,保存要比较的值。
struct Greater_than{
int val;
Greater_than(int v):val{v}{}
bool operator()(const pair<string,int> &r){return r.second>42;}
}
可以用lambda表达式代替(统计):
int cxx = count_if(m.begin(),m.end(),[](const pair<string,int> &r){return r.second>42;});