第五部分 – 标准库的使用
第五部分 标准库的使用SECTION 1 string类
·头文件:string
·名称空间:std
·特性:
1. string是模板具体化basic_string
2. size_type是一个依赖实现的整型,位于头文件string
3. string::npos为字符串的最大长度,通常为unsigned int的最大值.
·基础方法
方法 | 说明 |
size()、length() | 返回字符串的字符个数 |
operator[]() | 下标访问法 |
operator+() | 拼接字符串 |
operator=() | 赋值 |
·构造函数
构造函数 | 说明 |
string(const char *s); | 将string对象初始化为C风格字符串。 用法:string(要初始化为的C风格字符串); |
string(size_type n,char c); | 创建一个包含n个c字符的字符串。 用法string(需要的字符数,填充的字符); |
string(const string &str); | 复制构造函数 |
string(); | 默认构造函数 |
template string(Iter begin,Iter end); | 初始化为区间[begin,end)之间的字符,其包含begin不包含end.begin和end可以看做是指针(迭代器)。 用法:string(开始位置,结束位置); |
string(const string &str, size_type pos ,size_type n=npos); | 初始化为对象str中从位置pos开始到结尾的字符,或从位置pos开始的n个字符.用法:string(被操作string对象,开始位置,抽取字符数=到达结尾); |
string(string &&str) noexcept; | [C++11]初始化为str,并可能修改(移动构造函数) |
string(const char*s, size_type n); | 初始化为s的前n个字符,即使超过’\0′ 用法:string(要操作的C风格字符串,需要的长度) |
string( initializer_list | [C++11]初始化为花括号初始化列表里的字符. Initializer_list是初始化列表,如{1,2,3,4,5}; |
·string版getline()用法:getline(输入流对象,string对象);
该函数自动调整string大小
当读取的字符数达到最大值,设置failbit
·string的逻辑运算符均被重载。
·字符搜素:find()方法:
(1) size_type find(const string &str,size_type pos=0) const;
(2) size_type find(const char *s,size_type pos=0) const;
(3) size_type find(const char ch,size_type pos=0) const;
从字符串的pos位置查找子字符串str(或s)或字符ch的位置。
若找到,返回其首地址,否则返回 string::npos。
(1) (2)(3)用法:find(string字符串或C风格字符串或字符,开始位置=0);
(4)size_type find(const char *s,size_type pos,size_type n) ;从字符串的pos位置开始,查找s的前n个字符组成的字符串,返回方式同(1)(2).
用法:find(待取的C风格字符串,查找的开始位置,取的字符数);
·其他搜索:与find()的重载特征都相同
(1) rfind()查找子字符(串)最后一次出现的位置.
(2) find_first_of()查找参数中任何一个字符首次出现的位置
(3) find_last_of() 与(2)相仿,但查找最后一个
(4) find_first_not_of()查找第一个不包含在参数中的字符
(5) find_last_not_of()与(4)相仿,但查找最后一个
·其他方法:
capacity() 返回当前分配给字符串的内存块的大小
reserve(长度) 请求内存块的最小长度
c_str()返回对应的C风格字符串
**注:
模板basic_string有4个具体化,每个具体化都有一个typedef名称:
typedef basic_string
typedef basic_string
typedef basic_string
typedef basic_string
其原型如下:
template
class Allocator=allocator
charT是字符类型,traits是其特征,Allocator管理内存分配(使用 new和delete)
SECTION 2 智能指针
·头文件:memory
·模板:auto_ptr(C++98提出C++11废弃)、shared_ptr、unique_ptr
1. 共同特点:定义了类似指针的对象,可以将从new获得的地址赋给这种对象。过期后会自动使用delete删除。因此不能用于非堆空间。若使用了new[]分配内存,只能用unique_ptr
2. 创建和使用
auto_ptr模板的定义如下
template
其他两个模板类似。
其不会自动将指针转换为智能指针对象。声明X类型的智能指针方法:
智能指针模板名
智能指针支持常规的指针操作,能赋给相同类型的常规指针,还能赋给相同类型的智能指针。
3. 注意事项:
(1) 所有权:对于auto_ptr和unique_ptr,赋值会转让所有权,auto_ptr和unique_ptr只有一个智能指针可以拥有特定的对象,该指针才能删除对象。
(2) shared_ptr会跟踪引用智能指针,进行引用计数。仅在最后一个指针过期时才使用delete。
(3) auto_ptr转让所有权后不能使用它访问对象,auto能够直接使用=,但会带来悬空指针
(4) unique_ptr在转让所有权时,原指针不再指向有效数据,不能使用=进行赋值。
若原对象是一个临时右值(如函数返回时会创建临时对象,此时会立马剥夺临时对象的所有权并且立马销毁临时对象),允许进行赋值,如果将存在一段时间,则不能(以防止指针悬空)。
(5) std::move()将一个unique_ptr转换后返回,此时便可赋给另一个。用法move(源指针)。
(6) 模板auto_ptr使用new和delete;unique_ptr有使用new[] delete[]的版本,示例:
unique_ptr
SECTION 3 STANDARD TEMPLATE LIBRARY(STL,标准模板库)
·基础知识
1. STL包括了一组表示容器(类似数组)、迭代器(能够用来遍历容器的对象,与能够遍历数组的指针相似,是一个广义指针)、函数对象(类似于函数的对象)和算法(完成特定任务的过程)的模板。
2. 分配器:各种STL容器模板都接受一个可选的模板参数,该参数指定了使用哪一个分配器对象来管理内存。(使用的是new和delete)
3. 所有的STL容器提供的基本方法:
.size()容器中的元素个数
.swap()交换两个容器的内容
.begin()返回一个指向容器第一个元素的迭代器
.end()返回一个表示超过容器尾的指针
4. 每一个容器都定义了一个迭代器,为一个名为iterator的typedef,作用域为类。声明一个迭代器方法:
类名::iterator 迭代器名;
其可以:解除引用 operator*()、自增operator++()
E.g. vector
5. 超过结尾(past_the_end):指向容器最后一个元素后面的元素的迭代器
6. 某些STL容器特有的方法:
(1) push_back(追加的元素)将元素添加到末尾,并增加长度
(2) erase(开始迭代器,结束迭代器)删除制定区间的元素,接受两个迭代器(包含operator+()方法),包括开始不包括结束。
(3) insert(新元素的插入位置迭代器,被插入区间开始迭代器,被插入区间结束迭代器);用于插入元素,接受3个迭代器,包括开始不包括结束。
e.g.new_v.insert(new_v.begin(),old_v.begin(),old_v.end());
将矢量old_v的内容插入到矢量new_v的第一个元素前面
·算法 (头文件algorithm)
for_each(开始迭代器,结束迭代器,要应用的函数指针);前两个是一个容器的区间(不包括结束),最后是函数指针,会被应用于区间的各个元素,被指向的函数不能修改元素值。
random_shuffle(开始迭代器,结束迭代器);随机排列区间的元素,要求容器随机访问。
sort(开始迭代器,结束迭代器)
(开始迭代器,结束迭代器,自定义排序函数)
只接受区间时,使用<运算符,对区间升序排序。(要有对应的operator<()函数)
接受区间和函数指针时,函数返回值为false表示排序不正确.
·迭代器:
1. C++将operator++()作为前缀版本,将operator++(int)作为后缀版本。其中的参数根本不会使用,因此无需指定名称
2. 迭代器都能进行解除引用和比较
3.迭代器的类型:
(1) 输入迭代器:来自容器的信息被称为输入,可被程序用来读取容器中的信息,但不一定让程序修改,该种算法不修改值。(只读不写)
基于输入迭代器的任何算法都是单通行的,可以递增,不可倒退。
(2) 输出迭代器:将信息从程序传输给容器的迭代器。只能解除引用修改容器值,不能读取。(只写不读)输出迭代器是单通行的。
(3) 正向迭代器:与输入迭代器和输出迭代器相似,只用++运算符遍历容器。每次沿容器向前移动一个元素。总是按照相同的顺序遍历一系列的值。仍可以对以前的值解除引用,能够读写数据,也可只读数据。
(4) 双向迭代器:包含了正向迭代器的特性,支持–运算符。
(5) 随机访问迭代器:能够直接跳转到任意元素(随机访问),包含了双向迭代器的特性,支持随机访问。
随机访问迭代器操作:a、b为迭代器值,n为整数,r为随机访问迭代器的变量或引用。这些表达式只有在容器区间内(包括超尾)才合法。其操作如下:
a+n 或 n+a:指向a所指向的元素后的第n个元素;
a-n:指向a所指向的元素前的第n个元素;
r+=n、r-=n:复合运算符;
a[n]同*(a+n);b-a减法;ab,a<=b,a>=b用来比较地址。
(6)
迭代器的性能
4.概念、改进与模型:
概念是一系列的要求;改进是概念上的继承(因为其无法使用C++的类继承来描述,如将指针用作迭代器);模型是概念的具体实现。
以下算法使用头文件algorithm
(1) STL std::sort()函数:接受指向容器(数组)的第一个元素的迭代器(指针)和指向超尾的迭代器(指针),用于排序。
用法:sort(首迭代器,超尾迭代器);
(2) STL std::copy()函数:从一容器复制元素到另一迭代器,前两个迭代器指出要复制的元素范围(输入迭代器),最后一个迭代器(输出迭代器)指出要将第一个元素复制到的位置(目的地)。
注意:目标容器要足够大。复制不同于插入,其会覆盖原有的数据。
用法copy(开始,结束,目的地);
头文件:iterator
(3) 将信息复制到输入输出和其他迭代器
适配器:用于将其他接口转为STL接口
①表示输出流的迭代器:ostream_iterator模板,其是一个适配器,可将其他的接口转换为STL接口用法:
ostream_iterator<被发送给输出流的数据类型,输出流所使用的字符类型>
迭代器名(输出流名称,每个数据的分隔符(字符串));
如:ostream_iterator
使用*cout_iterator++ =15即可复制,等价于cout<<15<<” ”;
可复制到输出流内使用数据,可以创建无名迭代器。
如:copy(dict.begin(),dict.end(),ostream_iterator
//ostream_iterator
②istream_iterator使istream输入可用作迭代器接口,拥有两个模板参数,声明方法:istream_iterator<读取的数据类型,输入流使用的字符类型>迭代器名(输入流名),使用cin代表cin管理输入流,省略构造函数表示输入失败。可将其运用到copy()算法中,直到EOF、不匹配或其他问题为止。样例:
copy(istream_iterator
③reverse_iterator(反向迭代器):对反向迭代器递增操作将导致其被递减。
vector类有rbegin()和rend()的成员函数,rbegin()返回指向超尾元素的反向迭代器(vector
若要反着打印容器内容,可以进行如下操作:
copy(dice.rbegin(),dice.rend(),ostream_iterator
反向指针通过先递减再解除引用解决问题。(即*rp将在*rp的当前值之前对迭代器解除引用。)
④插入迭代器:添加新的元素,不会覆盖已有的数据,并会自动分配内存来容纳新的内容
back_insert_iterator将容器插入到容器尾部
front_insert_iterator:插入到容器的前端
insert_iterator:将元素插入到其构造函数指定的位置前面
可以直接使用copy()函数。
限制如下:back_insert_iterator需要允许在尾部快速插入的容器(插入操作的时间复杂度为常数,如vector),front_insert_iterator需要允许在起始位置做时间固定插入的容器类型(如queue),insert_iterator没有限制。
这些迭代器将容器类型作为模板参数。back_insert_iterator的构造函数假设传递给它的类型有push_back()方法。声明front_insert_iterator大同小异。insert_iterator需要指出位置。他们的声明格式为:
back_insert_iterator <容器类型> 迭代器名(容器名);
front_insert_iterator <容器类型> 迭代器名(容器名);
insert_iterator<容器类型> 迭代器名(容器名,插入位置);
·容器:早期的11个容器类型:deque、list、queue、stack、vector、map、multimap、set、multiset和bitset。C++11新增容器:forward_list、unordered_map、unordered_mulitmap、unordered_set和unordered_mulitset。
1.容器的基本特征:
X表示容器;T表示存储在容器中的对象类型;a、b表示类型为X的值;r表示类型为X&的值;u表示类型为X的标识符。
表达式 | 返回类型 | 说明 | (时间)复杂度 |
X::iterator | 指向T的迭代器 | 正向迭代器 | 编译时间 |
X::value_type | T | T的类型 | 编译时间 |
X u; | 创建容器u(空) | 固定O(1) | |
X (); | 创建匿名空容器 | 固定O(1) | |
X u(a); X u=a; | 调用复制构造函数后u==a. | 线性O(n) | |
r=a | X& | 赋值运算符 | 线性O(n) |
a.begin() | 迭代器 | 指向第一个元素的迭代器 | 固定O(1) |
(&a)->~X() | void | 析构函数 | 线性O(n) |
a.end() | 迭代器 | 返回指向超尾元素的迭代器 | 固定O(1) |
a.size() | 无符号整型 | 返回元素个数 | 固定O(1) |
a.swap(b) | void | 交换a、b的内容 | 固定O(1) |
a==b a!=b与a==b相反 | 可转为bool | 如果a、b长度相等,相应的元素都相等,返回真。 | 线性O(n) |
复杂度描绘了执行操作所需要的时间。从快到慢依次为:编译时间、固定时间、线性时间。
2.C++11 新增的容器要求:rv表示类型为X的非常量右值
X u(rv); X u=rv; | 调用移动构造函数 | 线性 | |
a=rv; | X& | 调用移动赋值运算符 | 线性 |
a.cbegin() | const_iterator | 返回指向第一个元素的const迭代器 | 固定 |
a.cend() | const_iterator | 返回指向超尾元素的const迭代器 | 固定 |
移动操作可能修改源对象,还可能转让所有权,而不做任何复制。
3. 序列容器:(7种STL容器:deque、forward_list、queue、priority_queue、stack和vector)
(1) queue队列能够能够在队尾添加元素,在队首删除元素;deque表示双端队列允许在两端添加或删除元素(array也被归为序列容器)。
(2) 特征:按线性顺序排列,即存在第一个元素,最后一个元素,除了该两个元素处其他的元素前后都分别有一个元素。
(3)序列的要求:t表示类型为T的值,n表示整数,p、q、i、j表示迭代器(T可做存储在容器中值的类型)
①基本操作[注:区间[x,y)的范围包括x(起始)不包括y(结束)]
表达式 | 返回类型 | 说明 |
X a(n,t); X(n,t); | 声明一个由n个t值组成的序列,名称为a或匿名。 格式:X(需要的数量,需要的值) | |
X a(i,j); X (i,j); | 声明一个名为a(或匿名)的容器并初始化为区间[i,j)的内容。 格式:X(开始,结束/[区间]) | |
a.insert(p,t); | 迭代器 | 将t插入到p的前面 格式:insert(位置,待插入值) |
a.insert(p,n,t); | void | 将n个t插入到p的前面 格式:insert(位置,需要的数量,待插入值) |
a.insert(p,i,j); | void | 将区间[i,j)中的元素插到p前 格式:insert(要插入的位置,[区间]/开始位置,结束位置) |
a.erase(p); | 迭代器 | 删除p所指向的位置 格式:erase(删除位置) |
a.erase(p,q); | 迭代器 | 删除区间[p,q)中的元素 格式:erase([待删除的区间]/开始位置,结束位置) |
a.clean() | void | 清空容器 |
②可选要求:在允许的情况下,时间复杂度为固定时间。
表达式 | 返回类型 | 含义 | 容器 |
a.front | T& | *a.begin() | vector,list,deque |
a.back() | T& | *–a.end() | vector,list,deque |
a,push_front(t) | void | a.insert(a.begin(),t) | list,deque |
a.push_back(t) | void | a.insert(a.end(),t) | vector,list,deque |
a.pop_front(t) | void | a.erase(a.begin()) | list,deque |
a.pop_back(t) | void | a.erase(–a.end()) | vector,list,deque |
a[n] a.at(n) | T& | *(a.begin()+n) | vector,deque |
注意:at()方法会检查边界,若越界则引发out_of_range异常。
(4)序列容器的详解
·矢量类 std::vector 模板类vector即std::vector位于vector头文件中。 可以动态修改长度、可以随机访问元素、在尾部添加删除元素的时间固定、在头部中间删除元素复杂度为线性时间、它是可反转容器,拥有rbegin()和rend()、使用reverse_iterator可以反向遍历容器。 声明格式:vector<元素类型> 对象名(元素个数); 其类似于数组,可用operator[]()访问元素。(提供随机访问功能) | ||||||||||||||||
·deque双向队列[Double-ended Queue] 模板位于头文件deque 类似于vector容器,支持随机访问,从deque对象的开始位置插入和删除元素的时间是固定的。 | ||||||||||||||||
·list双向链表 模板位于list头文件中。 除了第一个和最后一个元素之外,每个元素都与前后的元素相链接,可以双向遍历。list链表中任一位置进行插入和删除的时间是固定的。list可以反转,但不支持数组表示法和随机访问。从容器插入或删除元素后,链表迭代器指向元素不变。
insert()和splice()的区别: insert()将原始区间的副本插入到目标地址;splice()将原始区间移到目标地址,在其执行后迭代器仍然有效。 非成员函数sort()需要随机访问迭代器。 | ||||||||||||||||
·[C++11]forward_list单链表 在单链表中,每个节点只链接到下一个节点,并没有链接到前一个节点。则它只要正向迭代器,它是不可反转容器,比list更简单。 | ||||||||||||||||
·queue队列[适配器类] queue模板位于头文集queue,不允许随机访问队列元素,不允许遍历队列,可以将元素添加到队尾,从队首删除元素,查看首尾的值,检查元素数目和测试是否为空。
| ||||||||||||||||
·priority_queue优先队列模板: 位于头文集queue中,支持操作与queue相同。主要区别在于其最大的元素被移到队首,内部默认底层类为vector,可以修改确定元素的比较方法,构造函数如下: priority_queue priority_queue | ||||||||||||||||
·stack栈: 位于stack头文件中,其特点是先入后出。 不允许随机访问遍历;允许压栈出栈,查看栈顶值,检查元素数目和栈是否为空。
| ||||||||||||||||
·array [C++11] 它是非STL容器,其长度固定,拥有成员operator[]和at(),可将STL算法用于它。 | ||||||||||||||||
4.关联容器:对容器概念上的另一改进。
关联容器将值与键关联起来,并使用键来查找值。
对于容器X,X::value_type指出了存储在容器中的值的类型,X::key_type指出了键的类型。提供了对元素的快速访问。允许插入新元素,但不能指定插入的位置。使用树实现,根节点链接1到2个节点,每个节点都如此,从而形成分支结构。STL提供4个关联容器:set、multiset(位于set头文件)、map、multimap(位于map头文件);set的值与键类型相同,键是唯一的,set的值就是键。multiset与set相似,只是可能有多个值相同。
在map中,值与键的类型不同,键是唯一的,每个键对应一个值,
multimap类似,只是一个键可以对应多个值。
(1) set集合 ①关联集合,可反转,可排序,且键是唯一的,不可以存储多个相同的值; ②声明:set<键值类型> 名称; 第二个模板参数是可选的,可以用来指示对键进行排序的比较函数或对象。默认用less<键值类型>。 ③通用函数[要先排序] set_unior()求并集(合并相同的值),前两个参数指定第一个集合的区间,接下来两个指定第二个集合的区间,第五个指定了插入的地方,即输出迭代器. 用法:set_unior(第一个集合的开始,第一个集合的结束/[第一个集合的区间],第二个集合的开始,第二个集合的结束/[第二个集合的区间],输出的位置); set_intersection()求交集、set_difference()求两集合之差的用法与上面相同 ④set的方法 lower_bound(键值)将键作为参数并返回一个迭代器,指向集合中第一个不小于键参数的成员 upper_bound(键值)将键作为参数并返回一个迭代器,指向集合中第一个大于键参数的成员 |
(2) multimap ①创建:multimap<键类型,数据类型> 名称; 第三个模板参数可选,用于指出对键进行排序的比较函数或对象,默认为less<>;为了将信息结合在一起,实际的值与键将进行结合,pair 数据项是按键排序的。 ②使用:模板pair的构造函数:pair<键类型,数据类型>(键,值); 使用insert(pair值)方法插入容器。对于pair对象可以用first和second来访问键与值。 ③获取multimap信息 成员函数count(键)接受键作为参数,返回具有该键的数目;成员函数lower_bound()和upper_bound()将键作为参数,原理与set的相同;成员函数equal_range()用键作为参数,返回两个迭代器 |
他们表示的区间与该键匹配。该方法将两个值封装在一个pair对象中,这个pair的两个模板参数均为迭代器。
5.无序关联容器:对容器概念的另一种改进。底层差别在于其基于数据结构哈希表,提供了效率。共4种:unordered_set、unordered_multiset、unordered_map、unordered_multimap.
·函数对象
函数对象,也叫函数符。主要以函数方式与operator()结合使用的任意对象。包括了函数名、函数指针和重载了operator()的类对象。
1.概念:
(1) 生成器:不用参数的函数符
(2) 一元函数:接受一个参数的函数符
(3) 二元函数:接受两个参数的函数符
(4) 返回bool的一元函数叫一元谓词
(5) 返回bool的二元函数叫二元谓词
提供给for_each()的函数符应是一元函数;sort()的其中一个版本将二元谓词作为第三个参数;list模板有一个将谓词作为参数的remove_if()成员,该函数将谓词应用于区间中的每个元素,如果谓词为true,则删除元素。即remove_if(表示删除条件的谓词);
E. g scores.remove_if(too_big);//too_big是谓词
2.预定义的函数符:
函数std::transform() 两个版本:
(1) 接受4个参数。前两个参数指定容器区间的迭代器,第三个指定结果复制到哪。最后一个参数是一元函数符,应用于区间每个元素,生成结果中的新元素。
即:transform(开始应用位置,结束位置/[应用区间],结果保存位置,要应用的函数符);
(2) 使用一个二元函数符,并将该函数应用于两个区间中的元素。它用第三个参数表示第二个区间的开始位置(没有结束位置,因为第一个区间表明了长度)
即:transform(开始应用位置,结束位置/[应用区间],第二个区间开始位置,结果保存位置,要应用的函数符);
E.g m8,gr8是vector
ostream_iterator
输出m8与gr8的每个元素的平均值。
(3) 运算符与对应函数符(头文件funtional):定义了多个模板类函数对象,即:函数符<类型>();如:plus
对于内置的运算符和重载的运算符均有函数符:
+ | plus | – | minus | * | multiplies | / | divides | % | modulus | |||
– | negate | |||||||||||
== | equal_to | != | not_equal_to | > | greater | |||||||
< | less | >= | greater_equal | <= | less_equal | |||||||
&& | logical_and | || | logical_or | ! | logical_not | |||||||
3.自适应函数符与函数适配器
自适应函数符:携带了标识参数类型与返回类型的typedef成员。这些成员的名称:result_type、first_argument_type、second_argument_type.
如:plus
意义:函数适配器对象可以使用函数对象,并认为存在这些typedef成员。
STL使用binder1st和、binder2nd类自动完成将自适应二元函数转换为一元函数(函数适配器)
(1) binder1st若有一个自适应二元函数对象,则可以创建一个binder1st对象,该对象与一个将被用做该函数的第一个参数的值相关联。即:binder1st(自适应二元函数,关联的值) 函数符名;
如:binder1st(f2,val) f1;则f1(x)等价于f2(val,x)
bind1st函数可以简化过程,其返回一个函数符。用法:
bind1st(要转换的函数符,要绑定的第一个参数)。
(2) binder2nd类和bind2nd:与binder1st和bind1st类似,但是关联第二个参数。
·算法
1.非成员函数算法[STL函数可用于常规数组]概论:
可以用==比较不同容器,重载的运算符使用迭代器来比较内容。
算法分为4组:非修改式序列操作、修改式序列操作、排序和相关操作(头文件algorithm)、通用数字运算(头文件numeric)
2.算法:
(1) 就地算法:结果在原容器中;
(2) 复制算法:将结果拷贝到另一位置;
(3) 有些算法有就地与复制两个版本。复制版本以_copy,将额外接受一个输出迭代器参数,作为结果存放的位置。
(4) replace()函数原型:
template
void replace(ForwardIterator first,ForwardIterator last,
const &T old_vaule,const &T new_vaule);
所有的old_vaule将被替换为new_vaule.
即:replace(开始位置,结束位置/[应用区间],待替换的旧值,替换后的新值);
template
OutputIterator replace(InputIterator first,
InputIterator last,OutputIterator result,
const &T old_vaule,const &T new_vaule);
复制版本在第三个参数指定了一个名为result的新位置,将结果复制过去。对于复制算法,返回一个迭代器,指向复制的值的超尾。
即:输出迭代器 replace(开始位置,结束位置/[应用区间],输出的位置,待替换的旧值,替换后的新值);
以if结尾的版本将函数应用于容器元素的结果来执行操作,如果将函数应用于旧值中,返回值为true则replace_if()把旧值替换为新值。原型如下
template
void replace(ForwardIterator first,ForwardIterator last,
Predicate pred,const &T new_vaule);
即:replace(开始位置,结束位置/[应用区间],判断是否替换的谓词,替换后的新值);
(5) STL和string类:string类包括了begin()、end()、rbegin()、rend()等成员,可使用STL接口。next_permutation()算法将区间内容转为下一种排列方式。对于字符串,排列按照字母递增的顺序进行。如果成功,返回true;如果该区间已经处于最后的序列中,该算法返回false.要得到所有的排列,应先排序。
用法:next_permutation(开始排列位置,结束位置/[排列的区间]);
(6) 如果la和lb均为list
la.remove(4);remove(lb.begin(),lb.end(),4);
list链表使用remove()来删除某一实例,STL remove()函数接受区间并删除实例,但其不能调整容器长度。它将没有删除的元素放在链表开头,并返回新的超尾值。
(7) 使用STL:count()函数,将一个区间和一个值作为参数,并返回这个值在出现的次数。即count([区间],值);
map类可以用数组表示法将键作为索引访问存储值。
·其他库
1.vector、valarray、array
valarray不是STL的一部分,array提供了STL的方法
valarray重载了所有的算术运算符,如+表示每个元素相加,*表示每个元素相乘,其他的大体相似。
valarray重载了许多数学函数,其接受一个valarray对象并返回结果。如valarray
也可以使用apply()方法,传入函数进行运算,其不修改调用对象,返回一个包含结果的新对象。
valarray有resize()方法,不能自动调整大小。
C++11提供了接受valarray对象作为参数的begin()和end(),满足STL的区间要求。
如果numbers是valarray
valarray
下标指定slice类:用作下标索引,被初始化为3个整数值:
起始索引,索引数,步长(元素的距离)。如slice(1,4,3)指索引1,4,7,10.
头文件:initializer_list
2.initializer_list类[C++11]
(1) 如果类包含接受initializer_list作为参数的构造函数,则{}表示法会调用它。
(2) 所有initializer_list元素的类型必须相同。
(3) 使用:该模板包含begin()、end()、size()。
声明:initializer_list<类型> 名称={列表};
可以按值或引用传递。函数参数可以是initializer_list字面量,也可以是其变量。其迭代器类型为const,不能修改值,但可以互相赋值。
SECTION 4 标准输入输出、文件I/O
<暂缺>
