STL学习笔记(变动性算法)

本节描述的算法会变动区间内的元素内容。有两种方法可以变动元素内容:

1.运用迭代器遍历序列的过程中,直接加以变动

2.将元素从源区间赋值到目标区间的过程中加以变动

复制(copy)元素

OutputIterator

copy(InputIterator sourceBeg,

InputIterator sourceEnd,

OutputIterator destBeg)

BiderectionalIterator

copy_backward(BidirectionalIterator sourceBeg,

BidirectionalIterator sourceEnd,

BidirectionalIterator destEnd)

1.这两个算法都将源区间[sourceBeg,sourceEnd)中的所有元素赋值到以destBeg为起点或以destEnd为终点的目标区间去

2.返回目标区间内最后一个被赋值元素的下一位置,也就是第一个违背覆盖的元素的位置

3.destBeg或destEnd不可处于[sourceBeg,sourceEnd)区间内

下面的例子展示copy()的一些简单用法

 1 #include <iterator>
 2 #include "algostuff.hpp"
 3 using namespace std;
 4
 5 int main()
 6 {
 7     vector<int> coll1;
 8     list<int> coll2;
 9     INSERT_ELEMENTS(coll1,1,9);
10     copy(coll1.begin(),coll1.end(),back_inserter(coll2));
11     copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," "));
12     cout<<endl;
13     copy(coll1.rbegin(),coll1.rend(),coll2.begin());
14     copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," "));
15     cout<<endl;
16 }

转换(Transforming)和结合(Combining)元素

算法transform()提供一下两种能力:

1.转换元素

OutputIterator

transform(InputIterator sourceBeg,InputIterator sourceEnd,

OutputIterator destBeg,UnaryFunc op)

针对源区间[sourceBeg,sourceEnd)中的每一个元素调用 op(elem),并将结果写到以destBeg起始的目标区间内。

下面这个例子展示了transform()的转换元素功能

 1 #include <iterator>
 2 #include "algostuff.hpp"
 3 using namespace std;
 4
 5 int main()
 6 {
 7     vector<int> coll1;
 8     list<int> coll2;
 9     INSERT_ELEMENTS(coll1,1,9);
10     PRINT_ELEMENTS(coll1,"coll1: ");
11     transform(coll1.begin(),coll1.end(),coll1.begin(),negate<int>());
12     PRINT_ELEMENTS(coll1,"negated: ");
13     transform(coll1.begin(),coll1.end(),back_inserter(coll2),bind2nd(multiplies<int>(),10));
14     PRINT_ELEMENTS(coll2,"coll2: ");
15     transform(coll2.rbegin(),coll2.rend(),ostream_iterator<int>(cout," "),negate<int>());
16     cout<<endl;
17 }

2.将两序列的元素加以结合

OutputIterator

transform(InputIterator source1Beg,InputIterator source1End,

InputIterator source2Beg,

OutputIterator destBeg,

BinaryFunc op)

针对第一源区间[source1Beg,source1End)以及“从source2Beg开始的第二个源区间“对应的元素,调用:

op(source1Elem,source2Elem) 并将结果以destBeg起始的目标区间内。

下面这个例子展示以上所说的transform()用法:

 1 #include <iterator>
 2 #include "algostuff.hpp"
 3 using namespace std;
 4
 5 int main()
 6 {
 7     vector<int> coll1;
 8     list<int> coll2;
 9     INSERT_ELEMENTS(coll1,1,9);
10     PRINT_ELEMENTS(coll1,"coll1: ");
11     transform(coll1.begin(),coll1.end(),coll1.begin(),coll1.begin(),multiplies<int>());
12     PRINT_ELEMENTS(coll1,"squared: ");
13     transform(coll1.begin(),coll1.end(),coll1.rbegin(),back_inserter(coll2),plus<int>());
14     PRINT_ELEMENTS(coll2,"coll2: ");
15     cout<<"diff: ";
16     transform(coll1.begin(),coll1.end(),coll2.begin(),ostream_iterator<int>(cout," "),minus<int>());
17     cout<<endl;
18 }

互换(Swapping)元素内容

ForwardIterator

swap_ranges(ForwardIterator beg1,ForwardIterator end1,

ForwardIterator beg2)

1.强区间[beg1,end1)内的元素和”从beg2开始的区间“内的对应元素互换

2.返回第二区间中”最后一个被交换元素“的下一位置

下面这个例子展示swap_ranges()的用法

 1 #include "algostuff.hpp"
 2 using namespace std;
 3
 4 int main()
 5 {
 6     vector<int> coll1;
 7     deque<int> coll2;
 8     INSERT_ELEMENTS(coll1,1,9);
 9     INSERT_ELEMENTS(coll2,11,23);
10     PRINT_ELEMENTS(coll1,"coll1: ");
11     PRINT_ELEMENTS(coll2,"coll2: ");
12     deque<int>::iterator pos;
13     pos=swap_ranges(coll1.begin(),coll1.end(),coll2.begin());
14     PRINT_ELEMENTS(coll1,"\ncoll1: ");
15     PRINT_ELEMENTS(coll2,"coll2: ");
16     if(pos!=coll2.end())
17         cout<<"first element not modified: "<<*pos<<endl;
18     swap_ranges(coll2.begin(),coll2.begin()+3,coll2.rbegin());
19     PRINT_ELEMENTS(coll2,"\ncoll2:");
20 }

赋予(Assigning)新值

1.赋予完全相同的数值

void

fill(ForwardIterator beg,ForwardIterator end,

const T& newValue)

void

fill(ForwardIterator beg,Size num,

const T& newValue)

1.fill()将区间[beg,end)内的每一个元素都赋予新值newValue

2.fill_n()将”从beg开始的前num个元素“赋予新值newValue

3.调用者必须确保目标区间有足够空间,要不就得用插入行迭代器

以下程序展示fill()和fill_n()的用法

 1 #include <iterator>
 2 #include "algostuff.hpp"
 3 using namespace std;
 4
 5 int main()
 6 {
 7     fill_n(ostream_iterator<float>(cout," "),10,7.7);
 8     cout<<endl;
 9     list<string> coll;
10     fill_n(back_inserter(coll),9,"hello");
11     PRINT_ELEMENTS(coll,"coll: ");
12     fill(coll.begin(),coll.end(),"again");
13     PRINT_ELEMENTS(coll,"coll: ");
14     fill_n(coll.begin(),coll.size()-2,"hi");
15     PRINT_ELEMENTS(coll,"coll: ");
16     list<string>::iterator pos1,pos2;
17     pos1=coll.begin();
18     pos2=coll.end();
19     fill(++pos1,--pos2,"hmmm");
20     PRINT_ELEMENTS(coll,"coll: ");
21 }

2.赋予新产生的数值

void

generate(ForwardIterator beg,ForwardIterator end,

Func op)

void

generate_n(OutputIterator beg,Size num,

Func op)

1.generate()会调用以下动作:op() ,并赋值给区间[beg,end)内的每个元素

2.generate_n()会调用以下动作: op(),并赋值给”以beg起始的区间“内的前num个元素

以下程序展示如何利用generate()和generatr_n()安插和赋值一些随机数

 1 #include <cstdlib>
 2 #include "algostuff.hpp"
 3 using namespace std;
 4
 5 int main()
 6 {
 7     list<int> coll;
 8     generate_n(back_inserter(coll),5,rand);
 9     PRINT_ELEMENTS(coll);
10     generate(coll.begin(),coll.end(),rand);
11     PRINT_ELEMENTS(coll);
12 }

替换(Replacing)元素

1.替换序列内的元素

void

replace(ForwardIterator beg,ForwardIterator end,

const T& oldValue,const T& newValue)

void

replace_if(ForwardIterator beg,ForwardIterator end,

UnaryPredicate op,const T& newValue)

1.replace()将区间[beg,end)之内每一个”与oldValue相等“的元素替换成newValue

2.replace_if()将区间[beg,end)之内每一个以下一元判断式:op(elem)返回true的元素替换成newValue

以下程序示范replace()和replace_if()的用法

 1 #include "algostuff.hpp"
 2 using namespace std;
 3
 4 int main()
 5 {
 6     list<int> coll;
 7     INSERT_ELEMENTS(coll,2,7);
 8     INSERT_ELEMENTS(coll,4,9);
 9     PRINT_ELEMENTS(coll,"coll: ");
10     replace(coll.begin(),coll.end(),6,42);
11     PRINT_ELEMENTS(coll,"coll: ");
12     replace_if(coll.begin(),coll.end(),bind2nd(less<int>(),5),0);
13     PRINT_ELEMENTS(coll,"coll: ");
14 }

2.复制并替换元素

OutputIterator

replace_copy(InputIterator sourceBeg,InputIterator sourceEnd,

OutputIterator destBeg,

const T& oldValud,const T& newValue)

OutputIterator

replace_copy_if(InputIterator sourceBeg,InputIterator sourceEnd,

OutputIterator destBeg,

UnaryPredicate op,const T& newValue)

1.replace_copy()是copy()和replace()的组合。他将源区间[beg,end)中的元素赋值到”以destBeg为起点“的目标区间

同时将其中”与oldValue相等“的所有元素替换为newValue

2.replace_copy()是copy()和replace_if()的组合。

以下程序示范如何使用replace_copy()和replace_copy_if()

 1 #include <iterator>
 2 #include "algostuff.hpp"
 3 using namespace std;
 4
 5 int main()
 6 {
 7     list<int> coll;
 8     INSERT_ELEMENTS(coll,2,6);
 9     INSERT_ELEMENTS(coll,4,9);
10     PRINT_ELEMENTS(coll);
11     replace_copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "),5,55);
12     cout<<endl;
13     replace_copy_if(coll.begin(),coll.end(),ostream_iterator<int>(cout," "),bind2nd(less<int>(),5),0);
14     cout<<endl;
15 }

时间: 2024-11-10 11:51:49

STL学习笔记(变动性算法)的相关文章

STL学习笔记(算法概述)

算法头文件 要运用C++标准程序库的算法,首先必须包含头文件<algorithm> 使用STL算法时,经常需要用到仿函数以及函数配接器.它们定义域<functional>头文件中. 算法的分类 可以按以下分类方式描述各个STL算法: 非变动性算法(nonmodifying algorithms) 变动性算法(modifying algorithms) 移除性算法(removing algorithms) 变序性算法(mutating algorithms) 排序算法(sorting

算法学习笔记 KMP算法之 next 数组详解

最近回顾了下字符串匹配 KMP 算法,相对于朴素匹配算法,KMP算法核心改进就在于:待匹配串指针 i 不发生回溯,模式串指针 j 跳转到 next[j],即变为了 j = next[j]. 由此时间复杂度由朴素匹配的 O(m*n) 降到了 O(m+n), 其中模式串长度 m, 待匹配文本串长 n. 其中,比较难理解的地方就是 next 数组的求法.next 数组的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀,也可看作有限状态自动机的状态,而且从自动机的角度反而更容易推导一些. "前

STL学习笔记--&gt;初识STL

“这里要用char类型”; “这里要用int类型”; “其实实现这个方法只需要把另一个方法的返回值的类型和传入参数的类型改成float类型就实现了”; “其实这个算法只需要把以前写的那个稍微改动一下就行了”; ……………… 学过面向对象语言的都知道GP这个概念,就是泛型程序设计,说的再明白点就是编写不依赖于具体数据类型的程序,C++作为一门面向对象语言,当然也有泛型这个概念,这就不得不提STL(Standard Template Library,标准模板库),是被融入C++标准程序库里面的一个高

STL学习笔记(非变动性算法)

辅助函数 本节跟以后几节将对所有STL算法逐一详细讨论.为了简化这些例子,我们使用了一些辅助函数,分别用于对容器进行输出跟插入操作. for_each()算法 for_each()算法非常灵活,它可以以不同的方式存取.处理.修改每一个元素 UnaryProc for_each(InputIterator beg,InputIterator end,UnaryProc op); 1.对与区间[beg,end)中的每一个元素调用:op(elem) 2.返回op(已在算法内部被变动过)的一个副本 3.

STL学习笔记(已序区间算法)

针对已序区间执行的算法,执行前提是源区间必须在某个排序准则下已序. 搜寻元素(Searching) 1.检查某个元素是否存在 bool binary_search(ForwardIterator beg,ForwardIterator end, const T& value) bool binary_search(ForwardIterator beg,ForwardIterator end, const T& value, BinaryPredicate op) 以下示范binary_s

STL学习笔记(变序性算法)

变序性算法改变元素的次序,但不改变元素值. 这些算法不能用于关联式容器,因为在关联式容器中,元素有一定的次序,不能随意变动. 逆转元素次序 void reverse(BidirectionalIterator beg,BidirectionalIterator end) OutputIterator reverse_copy(BidirectionalIterator sourceBeg,BidirectionalIterator sourceEnd, OutputIterator destBe

STL学习笔记

这篇笔记暂时只是一部分,后续的部分会慢慢贴出来.有错误之处还望大神指教 1,容器 (1)vector vector要求<vector>的头文件包含,实际的实现是在<stl_vector.h>中. vector的初始化方式: 1,直接初始化空: vector():start(0),end(0),end_of_storage(0){}; ex: vector<int> vec; 2,初始化并赋值 vector<int/double/long/decimal/float

STL学习笔记(string)

动机 C++标准程序库中的string class使我们可以将string当做一个一般型别.我们可以像对待基本型别那样地复制.赋值和比较string, 再也不必但系内存是否足够.占用的内存实际长度等问题. 操作函数 1.构造函数和析构函数 下表列出string的所有构造函数和析构函数 2.大小和容量 size()和length():返回string中现有的字符个数. max_size():返回一个string最多能够包含的字符数,这个跟机器本身的限制有关系. capacity():重新分配内存之

STL学习笔记(第五章 STL组件)

STL组件 若干精心勾画的组件共同合作,构筑起STL的基础.这些组件最关键的是容器.迭代器和算法. 下图演示了STL组件之间的合作 容器(Containers) 容器类别(简称容器)用来管理一组元素.为了适应不同需求,STL提供了不同类型的容器. 总的来说,容器可分为两类: 1.序列式容器Sequence containers,此乃可序群集,其中每个元素均有固定位置(取决于插入时机和地点,和元素值无关). STL提供三个定义好的序列式容器:vector.deque和list. 2.关联式容器As