本文主要是介绍【C++提高编程-07】----C++ STL常用算法之遍历算法和算术生成算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🎩 欢迎来到技术探索的奇幻世界👨💻
📜 个人主页:@一伦明悦-CSDN博客
✍🏻 作者简介: C++软件开发、Python机器学习爱好者
🗣️ 互动与支持:💬评论 👍🏻点赞 📂收藏 👀关注+
如果文章有所帮助,欢迎留下您宝贵的评论,
点赞加收藏支持我,点击关注,一起进步!
前言
STL(Standard Template Library)是C++标准库的一部分,提供了丰富的数据结构和算法,用于处理数据和实现常见的计算任务。STL中的算法分为几类,包括遍历算法、修改算法、排序算法、查找算法、数值算法等,每类算法都有其特定的应用场景和功能。
正文
01-遍历算法之for_each用法
for_each是一种遍历算法,用于对指定范围内的每个元素执行特定操作。它的使用方式相对简单,但需要传入一个函数或函数对象作为操作的执行体。以下是关于for_each的详细介绍和用法示例:
for_each用法详解语法
template <class InputIterator, class Function> Function for_each(InputIterator first, InputIterator last, Function f);
InputIterator:表示容器或范围的起始位置的迭代器。Function:表示执行的操作,可以是函数或函数对象(仿函数)。参数
first:表示要处理的范围的起始位置。last:表示要处理的范围的结束位置,不包含在范围内。f:表示要执行的操作,可以是函数或函数对象。功能
for_each对[first, last)范围内的每个元素执行f操作。返回值
返回值类型为
Function,通常是传入的函数或函数对象f。示例
假设有一个整数数组
numbers,我们想要将每个元素加倍并输出结果。可以这样使用for_each:#include <iostream> #include <vector> #include <algorithm>void doubleAndPrint(int x) {std::cout << x * 2 << " "; }int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用 for_each 执行操作std::for_each(numbers.begin(), numbers.end(), doubleAndPrint);return 0; }输出结果将是
2 4 6 8 10,这里doubleAndPrint函数就是传入for_each的操作函数。在实际使用中,可以根据需要定义不同的操作函数或使用 lambda 表达式作为for_each的操作体。注意事项
for_each并不会改变容器中元素的值,它只是对每个元素执行操作。- 传入的操作函数或函数对象应符合对应的参数和返回值要求,以确保正确执行操作。
通过灵活运用
for_each算法,可以简化遍历操作的代码,提高代码的可读性和维护性。
下面给出具体代码分析应用过程
这段代码展示了如何使用 for_each 算法进行遍历操作,分别使用普通函数和函数对象作为操作体。让我简要解释一下这部分代码:
-
头文件包含:
#include <algorithm> #include <vector>这里包含了使用到的标准库头文件
<algorithm>和<vector>。 -
普通函数
print01:void print01(int val) {cout << val << " "; }print01是一个普通函数,用于打印传入的整数val。 -
函数对象
print02:class print02 { public:void operator()(int val){cout << val << " ";} };print02是一个函数对象(也称为仿函数),重载了函数调用运算符operator(),用于打印传入的整数val。 -
test01函数:void test01() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}// 使用 for_each 算法调用普通函数 print01for_each(v.begin(), v.end(), print01);cout << endl;// 使用 for_each 算法调用函数对象 print02for_each(v.begin(), v.end(), print02());cout << endl; }- 在
test01函数中,首先创建了一个vector<int>容器v,并将整数 0 到 9 添加到容器中。 - 然后使用
for_each算法分别调用了print01和print02函数对象,对容器v中的每个元素执行打印操作。
- 在
-
main函数:int main() {test01();system("pause");return 0; }main函数调用了test01函数,展示了for_each算法的基本用法和不同操作体的应用。
总结:
- 这段代码演示了如何使用
for_each算法对容器进行遍历操作,可以通过普通函数或函数对象来定义具体的操作。 - 函数对象的使用使得可以在一个地方定义多个不同的操作,增加了代码的灵活性和可复用性。
for_each算法不会修改容器中的元素,只是对每个元素执行指定的操作,这符合算法的设计初衷。
通过这样的方式,可以简化遍历操作的代码实现,并使代码更加清晰和易于维护。
#include <algorithm>
#include <vector>
//普通函数
void print01(int val)
{cout << val << " ";
}
//函数对象
class print02
{
public:void operator()(int val){cout << val << " ";}
};
//for_each算法基本用法
void test01() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}//遍历算法for_each(v.begin(), v.end(), print01);cout << endl;for_each(v.begin(), v.end(), print02());cout << endl;
}
int main() {test01();system("pause");return 0;
}
02-遍历算法之transform用法
transform是另一种常用的STL遍历算法,与for_each不同的是,它不仅可以对容器中的每个元素执行操作,还可以将操作的结果存储到另一个容器或同一容器的不同位置。以下是关于transform的详细介绍和用法示例:
transform用法详解语法
template <class InputIterator, class OutputIterator, class UnaryOperation> OutputIterator transform(InputIterator first1, InputIterator last1,OutputIterator result, UnaryOperation op);
InputIterator:表示容器或范围的起始位置的迭代器。OutputIterator:表示结果存储位置的迭代器。UnaryOperation:表示执行的操作,通常是一个函数对象(一元函数)。参数
first1:表示要处理的范围的起始位置。last1:表示要处理的范围的结束位置,不包含在范围内。result:表示操作结果的存储位置,可以是另一个容器的begin()迭代器或插入位置迭代器。op:表示要执行的操作,通常是一个函数对象,接受一个参数并返回结果。功能
transform对[first1, last1)范围内的每个元素应用op操作,并将结果存储到result指定的位置。返回值
返回一个指向存储结果的迭代器
result + (last1 - first1)。示例
假设有一个整数数组
numbers,我们想要将每个元素加倍并存储到另一个数组doubled_numbers中。可以这样使用transform:#include <iostream> #include <vector> #include <algorithm>// 定义一个函数对象,用于将元素加倍 struct Double {int operator()(int x) const { return x * 2; } };int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};std::vector<int> doubled_numbers;// 使用 transform 执行操作std::transform(numbers.begin(), numbers.end(), std::back_inserter(doubled_numbers), Double());// 输出结果for (auto num : doubled_numbers) {std::cout << num << " ";}std::cout << std::endl;return 0; }输出结果将是
2 4 6 8 10,这里Double是一个函数对象,作为transform的操作体。在实际使用中,也可以使用 lambda 表达式或其他函数对象来定义操作体op。注意事项
transform可以将操作的结果存储到另一个容器(如示例中的doubled_numbers),这对于在算法中生成新的数据集合非常有用。- 操作体
op必须是一个一元函数,接受一个参数并返回操作后的结果。- 如果
result容器的大小不足以容纳结果,则程序行为未定义;通常情况下应使用std::back_inserter等函数来动态扩展容器大小。通过
transform算法,可以将处理数据和存储结果有效地分离,提高了代码的模块化和可维护性,是处理数据转换和映射的常用工具之一。
下面给出代码分析应用过程:
这段代码演示了如何使用 transform 算法来对一个容器中的元素进行转换,并将结果存储到另一个容器中。让我来简要解释一下:
-
头文件包含:
#include <vector> #include <algorithm>这里包含了使用到的标准库头文件
<vector>和<algorithm>。 -
函数对象
TransForm:class TransForm { public:int operator()(int val){return val;} };TransForm是一个函数对象(仿函数),重载了函数调用运算符operator(),用于对传入的整数val进行转换操作。在这个例子中,它实际上是一个恒等函数,返回原始的输入值。 -
函数对象
MyPrint:class MyPrint { public:void operator()(int val){cout << val << " ";} };MyPrint是另一个函数对象,用于打印传入的整数val。 -
test01函数:void test01() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int> vTarget; // 目标容器vTarget.resize(v.size()); // 目标容器需要提前开辟空间// 使用 transform 算法对容器 v 中的每个元素应用 TransForm,并将结果存储到 vTarget 中transform(v.begin(), v.end(), vTarget.begin(), TransForm());// 使用 for_each 算法打印 vTarget 中的每个元素for_each(vTarget.begin(), vTarget.end(), MyPrint()); }- 在
test01函数中,首先创建了一个vector<int>容器v,并向其中插入整数 0 到 9。 - 创建了另一个
vector<int>容器vTarget作为目标容器,并调整其大小以匹配v的大小。 - 使用
transform算法对容器v中的每个元素应用TransForm函数对象,并将结果存储到vTarget中。 - 最后,使用
for_each算法和MyPrint函数对象打印vTarget中的每个元素。
- 在
-
main函数:int main() {test01();system("pause");return 0; }main函数调用了test01函数,展示了transform算法的基本用法和将操作结果存储到另一个容器的实际应用。
总结:
transform算法能够对一个容器中的元素进行操作,并将结果存储到另一个容器或同一容器的不同位置,比如示例中的vTarget。- 使用函数对象(如
TransForm和MyPrint)可以灵活定义操作,增强代码的可复用性和可维护性。 - 需要注意的是,目标容器在使用
transform算法之前需要预先分配足够的空间,以确保存储结果的正确性。
通过这样的方式,可以有效地进行数据转换和处理,使代码更加清晰和模块化。
#include<vector>
#include<algorithm>
//常用遍历算法 搬运 transform
class TransForm
{
public:int operator()(int val){return val;}
};
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};
void test01()
{vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int>vTarget; //目标容器vTarget.resize(v.size()); // 目标容器需要提前开辟空间transform(v.begin(), v.end(), vTarget.begin(), TransForm());for_each(vTarget.begin(), vTarget.end(), MyPrint());
}
int main() {test01();system("pause");return 0;
}
03-算术生成算法之accumulate用法
accumulate是另一个常用的STL算法,用于计算序列中元素的累加值。以下是关于accumulate的详细介绍和用法示例:
accumulate用法详解语法
template <class InputIterator, class T> T accumulate(InputIterator first, InputIterator last, T init);
InputIterator:表示容器或范围的起始位置的迭代器。T:表示累加结果的类型,通常是元素类型的累加结果类型。init:表示初始值,累加的起始点。参数
first:表示要累加的范围的起始位置。last:表示要累加的范围的结束位置,不包含在范围内。init:表示累加的初始值,累加从这个值开始。功能
accumulate对[first, last)范围内的元素进行累加,初始值为init,并返回累加的结果。返回值
返回累加后的结果,类型为
T。示例
假设有一个整数数组
numbers,我们想要计算数组中所有元素的累加和。可以这样使用accumulate:#include <iostream> #include <vector> #include <numeric> // 包含 accumulate 函数int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用 accumulate 计算累加和int sum = std::accumulate(numbers.begin(), numbers.end(), 0);std::cout << "Sum of elements: " << sum << std::endl;return 0; }输出结果将是
Sum of elements: 15。在这个例子中,accumulate函数将整数数组numbers中的所有元素累加起来,初始值为0。注意事项
accumulate可以用于各种数据类型,不限于整数。- 初始值
init的类型必须与累加结果的类型相容,通常为整数或浮点数。- 如果范围
[first, last)是空的,accumulate将直接返回初始值init。通过
accumulate算法,可以方便地计算序列中元素的累加和,是处理累加操作的常用工具之一。
下面给出具体代码分析应用过程:
这段代码展示了如何使用 accumulate 算法来计算整数向量中所有元素的累加和。让我来简要解释一下:
-
头文件包含:
#include <numeric> #include <vector>这里包含了使用到的标准库头文件
<numeric>和<vector>。 -
test01函数:void test01() {vector<int> v;for (int i = 0; i <= 100; i++) {v.push_back(i);}int total = accumulate(v.begin(), v.end(), 0);cout << "total = " << total << endl; }- 在
test01函数中,首先创建了一个vector<int>容器v,并使用循环将整数 0 到 100 插入到向量中。 - 调用
accumulate算法计算了容器v中所有元素的累加和。参数解释如下:v.begin()和v.end()表示累加的范围是从容器v的开头到末尾(不包括末尾)。0是累加的初始值,即从0开始累加。
- 将计算得到的总和
total输出到标准输出流cout中。
- 在
-
main函数:int main() {test01();system("pause");return 0; }main函数调用了test01函数,展示了accumulate算法的使用方式和计算结果的输出。
总结:
accumulate算法能够方便地对容器中的元素进行累加操作,从而计算它们的总和。- 初始值
0确保了即使容器为空,也能正确返回初始值作为累加结果。 - 使用
accumulate算法可以避免显式使用循环来计算累加和,简化了代码并提高了可读性。
通过这样的方式,可以快速、有效地处理需要累加操作的情况,适用于各种数据类型和复杂度的累加需求。
#include <numeric>
#include <vector>
void test01()
{vector<int> v;for (int i = 0; i <= 100; i++) {v.push_back(i);}int total = accumulate(v.begin(), v.end(), 0);cout << "total = " << total << endl;
}
int main() {test01();system("pause");return 0;
}
04-算术生成算法之fill用法
fill是STL中的一个算法,用于将指定范围内的所有元素设置为给定的值。以下是关于fill的详细介绍和用法示例:
fill用法详解语法
template <class ForwardIterator, class T> void fill (ForwardIterator first, ForwardIterator last, const T& value);
ForwardIterator:表示容器或范围的起始位置的迭代器类型。T:表示要填充的值的类型。first:表示要填充的范围的起始位置。last:表示要填充的范围的结束位置,不包含在范围内。value:表示要填充到范围中的值。参数
first:要填充的范围的起始位置。last:要填充的范围的结束位置,不包含在范围内。value:要填充到范围中的值。功能
fill算法用指定的值value填充[first, last)范围内的所有元素。返回值
无。
示例
假设有一个整数数组
numbers,我们想要将数组中的所有元素设置为0。可以这样使用fill:#include <iostream> #include <vector> #include <algorithm> // 包含 fill 函数int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用 fill 将数组中所有元素设置为 0std::fill(numbers.begin(), numbers.end(), 0);// 打印填充后的结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0; }输出结果将是
0 0 0 0 0。在这个例子中,fill函数将整数数组numbers中的所有元素都设置为0。注意事项
fill可以用于各种数据类型,不限于整数。- 使用
fill算法可以有效地初始化或重置容器中的元素。fill不检查last迭代器是否在范围内,使用时应保证范围有效。通过
fill算法,可以方便地将容器中的元素设置为指定值,是处理填充操作的常用工具之一。
下面给出具体代码分析应用过程:
这段代码演示了如何使用 fill 算法来填充整数向量中的所有元素为指定的值。让我来简要解释一下:
-
头文件包含:
#include <numeric> #include <vector> #include <algorithm> #include <iostream>这里包含了使用到的标准库头文件
<numeric>,<vector>,<algorithm>和<iostream>。 -
自定义函数对象
myPrint:class myPrint { public:void operator()(int val) {std::cout << val << " ";} };myPrint是一个重载了函数调用运算符()的类,用于在for_each算法中打印每个元素的值。 -
test01函数:void test01() {std::vector<int> v;v.resize(10); // 调整向量大小为10个元素// 使用 fill 算法将向量 v 中的所有元素设置为 100std::fill(v.begin(), v.end(), 100);// 使用 for_each 算法和自定义的 myPrint 函数对象打印向量中的每个元素std::for_each(v.begin(), v.end(), myPrint());std::cout << std::endl; }- 在
test01函数中,首先创建了一个大小为 10 的整数向量v。 - 使用
fill算法将向量v中的所有元素设置为100。v.begin()表示填充的起始位置,v.end()表示填充的结束位置(不包含在范围内)。 - 使用
for_each算法和自定义的myPrint函数对象,遍历打印向量v中的每个元素值。
- 在
-
main函数:int main() {test01();system("pause");return 0; }main函数调用了test01函数,展示了fill算法的使用方式和填充后的输出结果。
总结:
fill算法通过指定的值将容器中的指定范围内的所有元素进行填充。- 在本例中,
fill将整数向量v中的所有元素设置为100。 - 使用函数对象
myPrint可以在遍历过程中自定义操作,这里用于打印每个元素。 fill是初始化或重置容器元素的有效工具,能够简化代码并提高可读性。
通过这样的方式,可以快速、方便地对容器中的元素进行填充操作,适用于各种数据类型和填充需求。
#include <numeric>
#include <vector>
#include <algorithm>
class myPrint
{
public:void operator()(int val){cout << val << " ";}
};
void test01()
{vector<int> v;v.resize(10);//填充fill(v.begin(), v.end(), 100);for_each(v.begin(), v.end(), myPrint());cout << endl;
}
int main() {test01();system("pause");return 0;
}
总结
- 遍历算法帮助在容器内迭代元素并执行操作,如输出、转换或计算。
- 算术生成算法用于填充或生成容器的元素,常用于初始化和重置操作。
- 这些算法能够显著减少代码量并提高可读性,是C++中处理数据和容器操作的强大工具。
这篇关于【C++提高编程-07】----C++ STL常用算法之遍历算法和算术生成算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!