C++中合并STL容器需根据需求选择方法:使用std::merge可将两个已排序序列合并为有序序列,适用于有序合并场景;通过insert或splice实现简单拼接;利用std::set_union等算法处理集合操作以避免重复;对复杂对象需定义比较规则(如重载operator<或使用自定义比较器);合并不同类型元素时可通过共同基类指针存入同质容器。确保有序性需先排序再合并,去重可通过std::unique或使用std::set容器。

C++中对STL容器进行合并操作,核心在于理解你想要“合并”的具体含义。最直接且功能强大的方法是利用
std::merge
要实现STL容器的合并,我们主要依赖标准库提供的算法和容器自身的成员函数。
std::merge
当你的目标是将两个已排序的序列合并成一个新的已排序序列时,
std::merge
#include <iostream>
#include <vector>
#include <algorithm> // for std::merge
#include <iterator> // for std::back_inserter
int main() {
std::vector<int> vec1 = {1, 3, 5, 7, 9};
std::vector<int> vec2 = {2, 4, 6, 8, 10};
std::vector<int> merged_vec;
// 预留足够的空间,避免不必要的重新分配,提高效率
merged_vec.reserve(vec1.size() + vec2.size());
// 使用std::merge将vec1和vec2合并到merged_vec中
// std::back_inserter用于向vector末尾添加元素
std::merge(vec1.begin(), vec1.end(),
vec2.begin(), vec2.end(),
std::back_inserter(merged_vec));
std::cout << "Merged Vector: ";
for (int x : merged_vec) {
std::cout << x << " ";
}
std::cout << std::endl; // Output: 1 2 3 4 5 6 7 8 9 10
// 也可以自定义比较函数,例如降序合并
std::vector<int> vec3 = {9, 7, 5, 3, 1};
std::vector<int> vec4 = {10, 8, 6, 4, 2};
std::vector<int> merged_desc_vec;
merged_desc_vec.reserve(vec3.size() + vec4.size());
std::merge(vec3.begin(), vec3.end(),
vec4.begin(), vec4.end(),
std::back_inserter(merged_desc_vec),
std::greater<int>()); // 使用std::greater进行降序比较
std::cout << "Merged Descending Vector: ";
for (int x : merged_desc_vec) {
std::cout << x << " ";
}
std::cout << std::endl; // Output: 10 9 8 7 6 5 4 3 2 1
return 0;
}简单拼接 (Concatenation): 如果你只是想把一个容器的所有元素追加到另一个容器的末尾,而不关心排序,可以直接使用容器的
insert
push_back
立即学习“C++免费学习笔记(深入)”;
std::vector<int> a = {1, 2, 3};
std::vector<int> b = {4, 5, 6};
a.insert(a.end(), b.begin(), b.end()); // a 现在是 {1, 2, 3, 4, 5, 6}对于
std::list
splice
集合操作: 如果你处理的是集合(即元素唯一且通常有序),那么
std::set_union
std::set_intersection
std::set_difference
std::vector<int> s1 = {1, 2, 3, 4, 5};
std::vector<int> s2 = {3, 4, 5, 6, 7};
std::vector<int> union_result;
std::set_union(s1.begin(), s1.end(),
s2.begin(), s2.end(),
std::back_inserter(union_result));
// union_result: {1, 2, 3, 4, 5, 6, 7}确保数据有序性和避免重复是合并操作中非常常见的需求,尤其是在处理像日志、传感器数据或者用户ID列表这类场景。我个人觉得,这其实是合并操作的“高级形态”,因为它不仅仅是简单地堆叠数据。
对于有序性,
std::merge
std::vector
std::list
std::merge
std::sort
std::vector<int> unsorted_vec1 = {5, 1, 8, 3};
std::vector<int> unsorted_vec2 = {9, 2, 7, 4};
std::sort(unsorted_vec1.begin(), unsorted_vec1.end()); // 现在vec1是 {1, 3, 5, 8}
std::sort(unsorted_vec2.begin(), unsorted_vec2.end()); // 现在vec2是 {2, 4, 7, 9}
std::vector<int> result_vec;
result_vec.reserve(unsorted_vec1.size() + unsorted_vec2.size());
std::merge(unsorted_vec1.begin(), unsorted_vec1.end(),
unsorted_vec2.begin(), unsorted_vec2.end(),
std::back_inserter(result_vec));
// result_vec: {1, 2, 3, 4, 5, 7, 8, 9}如果忘记排序,
std::merge
至于避免重复元素,这通常需要额外的步骤或者选择特定的容器类型。
使用 std::set_union
std::set
std::unique
std::vector
std::set_union
先合并后去重: 如果输入序列可能含有重复元素,或者你先使用了
std::merge
std::vector<int> combined_with_duplicates = {1, 2, 2, 3, 4, 4, 5}; // 假设这是merge的结果
// std::unique将相邻的重复元素移到末尾,并返回新逻辑末尾的迭代器
auto last_unique = std::unique(combined_with_duplicates.begin(), combined_with_duplicates.end());
// 使用erase移除实际的重复元素
combined_with_duplicates.erase(last_unique, combined_with_duplicates.end());
// combined_with_duplicates: {1, 2, 3, 4, 5}需要注意的是,
std::unique
std::sort
std::unique
使用 std::set
std::map
std::set
std::map
std::vector<int> vec_a = {1, 5, 3, 5};
std::vector<int> vec_b = {2, 4, 1, 6};
std::set<int> unique_elements;
for (int x : vec_a) {
unique_elements.insert(x);
}
for (int x : vec_b) {
unique_elements.insert(x);
}
// unique_elements现在包含 {1, 2, 3, 4, 5, 6},自动排序且无重复这种方法的缺点是每次插入的开销是O(log N),对于大量元素,可能不如先合并到
vector
总结一下,要确保有序且无重复,通常的流程是:对源容器进行排序 -> 使用
std::merge
std::set_union
std::unique
std::set
当我们谈论合并不同类型或复杂对象的STL容器时,事情就变得有点意思了。简单地将
int
int
首先,明确一点:STL的合并算法(如
std::merge
std::vector<Person>
std::vector<Person>
std::vector<int>
std::vector<std::string>
当你的容器存储的是自定义的结构体或类对象时,比如
struct Person { std::string name; int age; };std::merge
std::sort
重载 operator<
operator<
struct Person {
std::string name;
int age;
// 重载 operator<,用于排序和合并
bool operator<(const Person& other) const {
if (name != other.name) {
return name < other.name;
}
return age < other.age;
}
};
// ... 之后你可以直接对 Person 对象的 vector 使用 std::sort 和 std::merge
std::vector<Person> team_a = {{"Alice", 30}, {"Bob", 25}};
std::vector<Person> team_b = {{"Charlie", 35}, {"Alice", 28}}; // 注意Alice重复但age不同
std::sort(team_a.begin(), team_a.end());
std::sort(team_b.begin(), team_b.end());
std::vector<Person> merged_team;
std::merge(team_a.begin(), team_a.end(),
team_b.begin(), team_b.end(),
std::back_inserter(merged_team));
// Merged: {{"Alice", 28}, {"Alice", 30}, {"Bob", 25}, {"Charlie", 35}} (按name, then age排序)这是一种侵入式的方法,意味着你的类需要知道如何比较自己。
提供自定义比较函数(Lambda/Functor): 如果你不想修改类定义,或者需要根据不同场景使用不同的比较逻辑,可以向
std::merge
// 假设 Person 类没有重载 operator<
struct Person {
std::string name;
int age;
};
// 定义一个 lambda 表达式作为比较器,按年龄排序
auto compare_by_age = [](const Person& p1, const Person& p2) {
return p1.age < p2.age;
};
std::vector<Person> team_a = {{"Alice", 30}, {"Bob", 25}};
std::vector<Person> team_b = {{"Charlie", 35}, {"Alice", 28}};
std::sort(team_a.begin(), team_a.end(), compare_by_age); // 使用年龄排序
std::sort(team_b.begin(), team_b.end(), compare_by_age);
std::vector<Person> merged_team_by_age;
std::merge(team_a.begin(), team_a.end(),
team_b.begin(), team_b.end(),
std::back_inserter(merged_team_by_age),
compare_by_age);
// Merged: {{"Bob", 25}, {"Alice", 28}, {"Alice", 30}, {"Charlie", 35}} (按age排序)这种方式非常灵活,可以在运行时决定比较策略。
std::merge
std::vector
std::list
#include <list>
// ... (其他头文件)
std::vector<double> vec_data = {1.1, 3.3, 5.5};
std::list<double> list_data = {2.2, 4.4, 6.6};
std::vector<double> merged_data;
merged_data.reserve(vec_data.size() + list_data.size());
std::merge(vec_data.begin(), vec_data.end(),
list_data.begin(), list_data.end(),
std::back_inserter(merged_data));
// merged_data: {1.1, 2.2, 3.3, 4.4, 5.5, 6.6}这挺强大的,它让我们能够混合搭配不同存储特性的容器,只要最终目标是统一的。
如果你的意思是,一个容器里是
int
std::string
std::merge
std::vector<T>
T
在这种情况下,你需要考虑:
共同基类或接口: 如果这些不同类型的对象都继承自一个共同的基类(或者实现了共同的接口),你可以使用
std::vector<std::unique_ptr<BaseClass>>
std::vector<BaseClass*>
class Shape { public: virtual void draw() const = 0; virtual ~Shape() = default; };
class Circle : public Shape { /* ... */ };
class Square : public Shape { /* ... */ };
std::vector<std::unique_ptr<Shape>> shapes1;
shapes1.push_back(std::make_unique<Circle>());
// ...
std::vector<std::unique_ptr<Shape>> shapes2;
shapes2.push_back(std::make_unique<Square>());
// ...
// 合并到新的容器
std::vector<以上就是C++如何使用STL容器进行合并操作的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号