探索C++ STL的算术与集合运算:从理论到实践
在C++编程中,标准模板库(STL)提供了强大的工具和算法,极大地简化了开发工作。本文将通过一系列代码示例,深入探讨STL中的算术运算和集合运算功能,帮助读者更好地理解和应用这些强大的工具。
一、STL算术运算:accumulate
函数
在处理数据时,经常需要对容器中的元素进行累加操作。STL中的accumulate
函数提供了一种简洁高效的方式来实现这一点。以下是一个简单的例子:
示例代码:accumulate.cpp
cpp复制
#include "me.h"
void test1()
{
vector<int> v;
for (int i = 0; i <= 100; i++)
{
v.push_back(i);
}
int sum = accumulate(v.begin(), v.end(), 0); // 使用accumulate计算累加和
cout << sum << endl;
}
在上述代码中,accumulate
函数接收三个参数:容器的起始迭代器、结束迭代器以及累加的初始值(这里是0)。它会依次将容器中的元素累加到初始值上,最终返回总和。对于v
中的元素(0到100),accumulate
函数计算出的总和为5050。
二、STL集合运算:set_union
、set_intersection
和set_difference
STL提供了多种集合运算算法,包括并集、交集和差集。这些算法适用于有序序列,能够高效地处理元素的合并、筛选等操作。
1. 并集运算:set_union
并集运算会将两个有序序列中的所有元素合并,并去除重复项。以下是一个示例代码:
示例代码:序列并集.cpp
cpp复制
#include "me.h"
class my_print
{
public:
void operator()(int a) const
{
cout << a << " ";
}
};
void test4()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i <= 7; i++)
{
v1.push_back(i);
v2.push_back(2 * i + 1);
}
for_each(v1.begin(), v1.end(), my_print());
cout << endl;
for_each(v2.begin(), v2.end(), my_print());
cout << endl;
vector<int> v;
v.resize(v1.size() + v2.size()); // 并集大小最多为两者长度和
vector<int>::iterator itend = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin());
for_each(v.begin(), itend, my_print()); // 输出并集结果
cout << endl;
}
在上述代码中,set_union
函数接收两个有序序列的起始和结束迭代器,以及目标容器的起始迭代器。它会将两个序列的并集存储到目标容器中,并返回并集的结束迭代器。对于v1
(0到7)和v2
(1到15的奇数),并集结果为0 1 2 3 4 5 6 7 9 11 13 15
。
2. 交集运算:set_intersection
交集运算会提取两个有序序列中的公共元素。以下是一个示例代码:
示例代码:序列交集.cpp
cpp复制
#include "me.h"
class my_print
{
public:
void operator()(int a) const
{
cout << a << " ";
}
};
void test3()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i <= 7; i++)
{
v1.push_back(i);
v2.push_back(2 * i + 1);
}
for_each(v1.begin(), v1.end(), my_print());
cout << endl;
for_each(v2.begin(), v2.end(), my_print());
cout << endl;
vector<int> v;
v.resize(min(v1.size(), v2.size())); // 交集大小最多为两者最小长度
vector<int>::iterator itend = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin());
for_each(v.begin(), itend, my_print()); // 输出交集结果
cout << endl;
}
在上述代码中,set_intersection
函数接收两个有序序列的起始和结束迭代器,以及目标容器的起始迭代器。它会将两个序列的交集存储到目标容器中,并返回交集的结束迭代器。对于v1
(0到7)和v2
(1到15的奇数),交集结果为空,因为两个序列没有公共元素。
3. 差集运算:set_difference
差集运算会提取一个有序序列中不属于另一个序列的元素。以下是一个示例代码:
示例代码:序列差集.cpp
cpp复制
#include "me.h"
class my_print
{
public:
void operator()(int a) const
{
cout << a << " ";
}
};
void test5()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i <= 7; i++)
{
v1.push_back(i);
v2.push_back(2 * i + 1);
}
for_each(v1.begin(), v1.end(), my_print());
cout << endl;
for_each(v2.begin(), v2.end(), my_print());
cout << endl;
vector<int> vd1;
vd1.resize(v1.size()); // A-B
vector<int>::iterator itend1 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vd1.begin());
for_each(vd1.begin(), itend1, my_print()); // 输出A-B的结果
cout << endl;
vector<int> vd2;
vd2.resize(v2.size()); // B-A
vector<int>::iterator itend2 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vd2.begin());
for_each(vd2.begin(), itend2, my_print()); // 输出B-A的结果
cout << endl;
}
在上述代码中,set_difference
函数接收两个有序序列的起始和结束迭代器,以及目标容器的起始迭代器。它会将第一个序列中不属于第二个序列的元素存储到目标容器中,并返回差集的结束迭代器。对于v1
(0到7)和v2
(1到15的奇数),A-B
的结果为0 2 4 6
,B-A
的结果为1 3 5 7 9 11 13 15
。
三、其他实用算法:fill
和for_each
除了上述的算术和集合运算,STL还提供了其他实用的算法,例如fill
和for_each
。
1. 填充操作:fill
fill
函数可以将容器中的所有元素设置为指定的值。以下是一个示例代码:
示例代码:fill.cpp
cpp复制
#include "me.h"
class my_print
{
public:
void operator()(int a) const
{
cout << a << " ";
}
};
void test2()
{
vector<int> v;
for (int i = 0; i <= 7; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), my_print());
cout << endl;
fill(v.begin(), v.end(), 1); // 将所有元素填充为1
for_each(v.begin(), v.end(), my_print());
cout << endl;
}
在上述代码中,fill
函数接收容器的起始和结束迭代器,以及要填充的值(这里是1)。它会将容器中的所有元素设置为指定的值。对于v
(0到7),填充后的结果为1 1 1 1 1 1 1 1
。
2. 遍历操作:for_each
for_each
函数可以对容器中的每个元素执行指定的操作。以下是一个示例代码:
示例代码:fill.cpp
cpp复制
#include "me.h"
class my_print
{
public:
void operator()(int a) const
{
cout << a << " ";
}
};
void test2()
{
vector<int> v;
for (int i = 0; i <= 7; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), my_print()); // 输出容器中的元素
cout << endl;
}
在上述代码中,for_each
函数接收容器的起始和结束迭代器,以及一个操作函数(这里是my_print
)。它会对容器中的每个元素执行指定的操作。对于v
(0到7),输出结果为0 1 2 3 4 5 6 7
。
四、总结
C++ STL提供了丰富的算法和工具,能够极大地简化开发工作。通过本文的介绍,读者可以了解到STL中算术运算(如accumulate
)和集合运算(如set_union
、set_intersection
和set_difference
)的强大功能。同时,fill
和for_each
等实用算法也为容器操作提供了便利。掌握这些工具,能够让程序员更加高效地处理数据,提升开发效率。
在实际开发中,合理运用STL算法可以避免重复造轮子,提高代码的可读性和可维护性。希望本文的介绍能够帮助读者更好地理解和应用C++ STL。