一、transform 算法
1、接收一个输入容器范围的 transform 算法函数原型
transform 算法函数原型 : 下面的函数原型作用是 将 一个输入容器 中的元素 变换后 存储到 输出容器 中 ;
template <class InputIt, class OutputIt, class UnaryOperation>
OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op);
-
参数解析 :
- InputIt first1 参数 : 输入容器 的 起始迭代器 ( 包含 ) ;
- InputIt last1 参数 : 输入容器 的 终止迭代器 ( 不包含 ) ;
- OutputIt d_first 参数 : 输出容器 的 开始迭代器 , 输出元素个数 根据 输入元素 的 范围确定 , transform 会将 变换结果存储到 输出容器中 ;
- UnaryOperation unary_op 参数 : 一元函数对象 , 将输入容器 的 每个元素 输入到该 一元函数对象 中 , 将计算结果 输出到 输出容器 中 ;
-
返回值解析 :
- 该 算法函数 返回 OutputIt 类型的 返回值是一个 迭代器 , 该迭代器指向最后一个被写入元素之后的位置 ;
2、代码示例 - 传入接受一个参数的普通函数
在下面的代码中 ,
首先 , 创建了一个 vector 数组容器 , 之后该容器 既作为输入容器 , 又作为输出容器 , 将元素输入后 , 计算后 , 在输出 到原来的容器中 ;
// 创建一个 vector 数组容器
vector<int> myVector;
然后 , 定义了一个 接受一个参数的 普通函数 , 使用该 函数 作为变换规则 ;
// 普通函数
int addone(int& n) {
return ++n;
}
最后 , 将 myVector 数组容器的 元素范围 ( 起始迭代器 和 末尾迭代器 ) 作为输入容器 , 将 myVector 数组容器的 的 起始迭代器 作为输出容器 起始点 , 也就是 将 输入容器 的元素 进行修改 , 再次放回到 该容器中 ;
// 向 transform 变换算法中 传入 普通函数
transform(myVector.begin(), myVector.end(), myVector.begin(), addone);
代码示例 :
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"
// 普通函数
int addone(int& n) {
return ++n;
}
int main() {
// 创建一个 vector 集合容器
vector<int> myVector;
// 向容器中插入元素
myVector.push_back(9);
myVector.push_back(5);
myVector.push_back(2);
myVector.push_back(7);
// 向 transform 变换算法中 传入 一元函数对象
transform(myVector.begin(), myVector.end(), myVector.begin(), addone);
// 遍历容器
for_each(myVector.begin(), myVector.end(), [](int element) {
cout << element << endl;
});
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
10
6
3
8
请按任意键继续. . .
3、代码示例 - 传入接受一个参数的 Lambda 表达式
在下面的代码中 ,
首先 , 创建了一个 vector 数组容器 , 之后该容器 既作为输入容器 , 又作为输出容器 , 将元素输入后 , 计算后 , 在输出 到原来的容器中 ;
// 创建一个 vector 数组容器
vector<int> myVector;
然后 , 定义了一个 接受一个参数的 Lambda 表达式 , 使用该 Lambda 表达式 作为变换规则 ;
// Lambda 表达式
[](int element) {
return ++element;
}
最后 , 将 myVector 数组容器的 元素范围 ( 起始迭代器 和 末尾迭代器 ) 作为输入容器 , 将 myVector 数组容器的 的 起始迭代器 作为输出容器 起始点 , 也就是 将 输入容器 的元素 进行修改 , 再次放回到 该容器中 ;
// 向 transform 变换算法中 传入 普通函数
transform(myVector.begin(), myVector.end(), myVector.begin(), [](int element) {
return ++element;
});
代码示例 :
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"
int main() {
// 创建一个 vector 集合容器
vector<int> myVector;
// 向容器中插入元素
myVector.push_back(9);
myVector.push_back(5);
myVector.push_back(2);
myVector.push_back(7);
// 向 transform 变换算法中 传入 Lambda 表达式
transform(myVector.begin(), myVector.end(), myVector.begin(), [](int element) {
return ++element;
});
// 遍历容器
for_each(myVector.begin(), myVector.end(), [](int element) {
cout << element << endl;
});
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
10
6
3
8
请按任意键继续. . .
4、代码示例 - 传入接受一个 一元函数对象 作为变换规则
在下面的代码中 ,
首先 , 创建了一个 vector 数组容器 , 之后该容器 既作为输入容器 , 又作为输出容器 , 将元素输入后 , 计算后 , 在输出 到原来的容器中 ;
// 创建一个 vector 数组容器
vector<int> myVector;
然后 , 定义了一个 一元函数对象 , 使用该 一元函数对象 作为变换规则 ;
// 一元函数对象
class AddOne{
public:
int operator()(int& n){
return ++n;
}
};
最后 , 将 myVector 数组容器的 元素范围 ( 起始迭代器 和 末尾迭代器 ) 作为输入容器 , 将 myVector 数组容器的 的 起始迭代器 作为输出容器 起始点 , 也就是 将 输入容器 的元素 进行修改 , 再次放回到 该容器中 ;
// 向 transform 变换算法中 传入 一元函数对象
auto AD = AddOne();
transform(myVector.begin(), myVector.end(), myVector.begin(), AD);
代码示例 :
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"
// 一元函数对象
class AddOne{
public:
int operator()(int& n){
return ++n;
}
};
int main() {
// 创建一个 vector 数组容器
vector<int> myVector;
// 向容器中插入元素
myVector.push_back(9);
myVector.push_back(5);
myVector.push_back(2);
myVector.push_back(7);
// 向 transform 变换算法中 传入 一元函数对象
auto AD = AddOne();
transform(myVector.begin(), myVector.end(), myVector.begin(), AD);
// 遍历容器
for_each(myVector.begin(), myVector.end(), [](int element) {
cout << element << endl;
});
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
10
6
3
8
请按任意键继续. . .
5、代码示例 - 传入接受一个 STL 中预定义的 一元函数对象 作为变换规则
在下面的代码中 ,
首先 , 创建了一个 vector 数组容器 , 之后该容器 既作为输入容器 , 又作为输出容器 , 将元素输入后 , 计算后 , 在输出 到原来的容器中 ;
// 创建一个 vector 数组容器
vector<int> myVector;
然后 , 使用STL 中预定义的 一元函数对象 negate 作为变换规则 ; 该 预定义函数对象 源码如下 , 可以看到直接将输入参数 进行取反 操作 , 在前面加上一个符号 " - " 返回 ;
// STRUCT TEMPLATE negate
template <class _Ty = void>
struct negate {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr _Ty operator()(const _Ty& _Left) const {
return -_Left;
}
};
最后 , 将 myVector 数组容器的 元素范围 ( 起始迭代器 和 末尾迭代器 ) 作为输入容器 , 将 myVector 数组容器的 的 起始迭代器 作为输出容器 起始点 , 也就是 将 输入容器 的元素 进行修改 , 再次放回到 该容器中 ;
// 向 transform 变换算法中 传入 预定义一元函数对象
transform(myVector.begin(), myVector.end(), myVector.begin(), negate<int>());
代码示例 :
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"
int main() {
// 创建一个 vector 集合容器
vector<int> myVector;
// 向容器中插入元素
myVector.push_back(-9);
myVector.push_back(5);
myVector.push_back(-2);
myVector.push_back(7);
// 向 transform 变换算法中 传入 预定义一元函数对象
transform(myVector.begin(), myVector.end(), myVector.begin(), negate<int>());
// 遍历容器
for_each(myVector.begin(), myVector.end(), [](int element) {
cout << element << endl;
});
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
9
-5
2
-7
请按任意键继续. . .
6、代码示例 - 传入接受一个 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
在下面的代码中 ,
首先 , 创建了一个 vector 数组容器 , 之后该容器 既作为输入容器 , 又作为输出容器 , 将元素输入后 , 计算后 , 在输出 到原来的容器中 ;
// 创建一个 vector 数组容器
vector<int> myVector;
然后 , 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象 ,
// 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
bind2nd(multiplies<int>(), 10)
multiplies 函数对象源码如下 : 该函数对象的 重载 函数调用操作符 函数 , 接收 2 个参数 , 使用 bind2nd 函数适配器 为其设置第二个参数为 10 , 那么第一个参数就是 迭代器范围的 元素 ;
// STRUCT TEMPLATE multiplies
template <class _Ty = void>
struct multiplies {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const {
return _Left * _Right;
}
};
最后 , 将 myVector 数组容器的 元素范围 ( 起始迭代器 和 末尾迭代器 ) 作为输入容器 , 将 myVector 数组容器的 的 起始迭代器 作为输出容器 起始点 , 也就是 将 输入容器 的元素 进行修改 , 再次放回到 该容器中 ;
// 向 transform 变换算法中 传入 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
transform(myVector.begin(), myVector.end(), myVector.begin(), bind2nd(multiplies<int>(), 10));
代码示例 :
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"
int main() {
// 创建一个 vector 集合容器
vector<int> myVector;
// 向容器中插入元素
myVector.push_back(9);
myVector.push_back(5);
myVector.push_back(2);
myVector.push_back(7);
// 向 transform 变换算法中 传入 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
transform(myVector.begin(), myVector.end(), myVector.begin(), bind2nd(multiplies<int>(), 10));
// 遍历容器
for_each(myVector.begin(), myVector.end(), [](int element) {
cout << element << endl;
});
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
90
50
20
70
请按任意键继续. . .
7、代码示例 - 将变换结果输出到标准输出流中
ostream_iterator 函数对象 是 一个模板类 , 其提供了一个输出迭代器 , 可以将元素逐个写入到输出流中 , 通常是 std::ostream 对象 , 如 std::cout 标准输出流 ;
ostream_iterator 函数对象 定义在 <iterator> 头文件中 , 使用前先导入该头文件 ;
// ostream_iterator 输出流迭代器 头文件
#include "iterator"
ostream_iterator 函数对象 的 构造函数接受两个参数 :
- 一个输出流对象的引用
- 一个可选的分隔符字符串 ;
每次迭代器被解引用以写入元素时 , 它都会将元素写入输出流 , 并在元素之间插入分隔符 ;
在下面的代码中 ,
首先 , 创建了一个 vector 数组容器 , 之后该容器 既作为输入容器 , 又作为输出容器 , 将元素输入后 , 计算后 , 在输出 到原来的容器中 ;
// 创建一个 vector 数组容器
vector<int> myVector;
然后 , 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象 ,
// 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
bind2nd(multiplies<int>(), 10)
multiplies 函数对象源码如下 : 该函数对象的 重载 函数调用操作符 函数 , 接收 2 个参数 , 使用 bind2nd 函数适配器 为其设置第二个参数为 10 , 那么第一个参数就是 迭代器范围的 元素 ;
// 向 transform 变换算法中 传入 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
// 将变换结果 , 输出到 屏幕 标准输出流 中
transform(myVector.begin(), myVector.end(), ostream_iterator<int>(cout, " "), bind2nd(multiplies<int>(), 10));
最后 , 将 myVector 数组容器的 元素范围 ( 起始迭代器 和 末尾迭代器 ) 作为输入容器 , 将 myVector 数组容器的 的 起始迭代器 作为输出容器 起始点 , 也就是 将 输入容器 的元素 进行修改 , 再次放回到 该容器中 ;
// 向 transform 变换算法中 传入 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
transform(myVector.begin(), myVector.end(), myVector.begin(), bind2nd(multiplies<int>(), 10));
代码示例 :
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"
// ostream_iterator 输出流迭代器 头文件
#include "iterator"
int main() {
// 创建一个 vector 集合容器
vector<int> myVector;
// 向容器中插入元素
myVector.push_back(9);
myVector.push_back(5);
myVector.push_back(2);
myVector.push_back(7);
// 向 transform 变换算法中 传入 使用 函数适配器 将预定义二元函数对象转成的 一元函数对象
// 将变换结果 , 输出到 屏幕 标准输出流 中
transform(myVector.begin(), myVector.end(), ostream_iterator<int>(cout, " "), bind2nd(multiplies<int>(), 10));
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :文章来源:https://www.toymoban.com/news/detail-810006.html
90 50 20 70 请按任意键继续. . .
文章来源地址https://www.toymoban.com/news/detail-810006.html
到了这里,关于【C++】STL 算法 - transform 变换算法 ② ( 变换规则为 普通函数 | 变换规则为 Lambda 表达式 | 变换规则为 函数对象 | 变换规则为 函数适配器转换的函数对象 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!