stl容器互相转换代码块

Posted by CongYu on January 1, 2020

STL 容器互相转换

必要的头文件

1
2
3
4
5
6
7
8
#include <vector>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>  // 用于 std::move, std::transform
#include <iterator>   // 用于 std::inserter, std::back_inserter

vector 相关转换

vector move to set

1
2
3
4
std::vector<int> nums_v{0, 1, 2, 3};
std::unordered_set<int> nums_set;
std::move(nums_v.begin(), nums_v.end(), std::inserter(nums_set, nums_set.end()));
// 注意:move后原vector变为空

vector move to list

1
2
3
4
std::vector<int> nums_v{0, 1, 2, 3};
std::list<int> nums_list;
std::move(nums_v.begin(), nums_v.end(), std::back_inserter(nums_list));
// 注意:move后原vector变为空

vector copy to set

1
2
3
std::vector<int> nums_v{0, 1, 2, 3};
std::unordered_set<int> nums_set;
nums_set.insert(nums_v.begin(), nums_v.end());

vector copy to list

1
2
std::vector<int> nums_v{0, 1, 2, 3};
std::list<int> nums_list(nums_v.begin(), nums_v.end());

set 相关转换

set move to vector

1
2
3
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v(std::make_move_iterator(nums_set.begin()), 
                       std::make_move_iterator(nums_set.end()));

set move to list

1
2
3
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::list<int> nums_list;
std::move(nums_set.begin(), nums_set.end(), std::back_inserter(nums_list));

注意:对于 set/unordered_set 这类元素为 const 的容器,move 语义和 copy 语义效果一致。

set copy to vector

1
2
3
4
5
6
7
8
9
10
11
12
13
// 方法1:使用构造函数
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v(nums_set.begin(), nums_set.end());

// 方法2:使用assign
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v;
nums_v.assign(nums_set.begin(), nums_set.end());

// 方法3:使用insert
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v;
nums_v.insert(nums_v.end(), nums_set.begin(), nums_set.end());

set copy to list

1
2
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::list<int> nums_list(nums_set.begin(), nums_set.end());

map 相关转换

map copy to vector of pairs

1
2
std::map<int, std::string> m{{1, "one"}, {2, "two"}};
std::vector<std::pair<int, std::string>> v(m.begin(), m.end());

map copy to vector of keys

1
2
3
4
std::map<int, std::string> m{{1, "one"}, {2, "two"}};
std::vector<int> keys;
std::transform(m.begin(), m.end(), std::back_inserter(keys),
              [](const auto& pair) { return pair.first; });

map copy to vector of values

1
2
3
4
std::map<int, std::string> m{{1, "one"}, {2, "two"}};
std::vector<std::string> values;
std::transform(m.begin(), m.end(), std::back_inserter(values),
              [](const auto& pair) { return pair.second; });

list 相关转换

list copy to vector

1
2
std::list<int> nums_list{0, 1, 2, 3};
std::vector<int> nums_v(nums_list.begin(), nums_list.end());

list copy to set

1
2
std::list<int> nums_list{0, 1, 2, 3};
std::unordered_set<int> nums_set(nums_list.begin(), nums_list.end());

注意事项

语义区别

  1. Move 语义:原容器中的元素会被移动,原容器变为空,性能更优
  2. Copy 语义:原容器保持不变,会产生额外的复制开销

容器特性

  1. 对于关联容器(如 set、map),转换到序列容器(如 vector、list)时需要注意元素顺序
  2. 对于 set/map 这类关联容器,元素类型为 const,move 语义和 copy 语义效果一致
  3. 对于 map 到 vector 的转换,通常需要指定转换的目标类型(key、value 或 pair)

性能考虑

  1. 大容器转换时优先使用 move 语义以避免不必要的复制
  2. 对于简单类型(如 int、double),move 和 copy 性能差异不大
  3. 对于复杂对象(如 string、自定义类),move 语义可以显著提升性能

使用技巧

  1. 使用 std::transform 时,可以自定义转换逻辑,非常灵活
  2. 构造函数方式通常比先创建空容器再插入的方式效率更高