← 目录 / 第十一章 · STL 标准模板库 / 11.13.3 复制、替换与移动

11.13.3 复制、替换与移动

copy、fill、replace、unique —— 批量改写容器内容的通用算法。

📂 引入头文件:#include <algorithm> —— 本节算法全部在这里。
本页目录
① copy —— 复制

把一段区间的元素逐个复制到另一个位置。目标位置需要预先分配好足够的空间——copy 不会自动帮目标容器扩容,只是简单地逐个赋值。

C++ · copy 把一个容器的内容复制到另一个
1vector<int> src = {1, 2, 3, 4, 5};
2vector<int> dst(5); // 目标容器需要预先分配空间
3copy(src.begin(), src.end(), dst.begin());
4// dst 变成 {1, 2, 3, 4, 5}
⚠️
如果 dst 是一个空的 vector(没有预分配空间),直接 copy 会越界访问、导致未定义行为。正确做法是先 dst.resize(src.size()) 或者在定义时就给够大小,就像例子里 vector<int> dst(5) 那样。
② fill —— 填充

把指定区间内的全部元素都设为同一个值,可以填充整个容器,也可以只填充一部分。

C++ · fill 批量赋值
1vector<int> v(5);
2fill(v.begin(), v.end(), 42);
3// v 变成 {42, 42, 42, 42, 42}
4
5// 填充前 3 个
6fill(v.begin(), v.begin() + 3, 7);
7// v 变成 {7, 7, 7, 42, 42}
📌
给一个数组/vector 整体清零或者初始化成某个固定值时,fill 比手写 for 循环更简洁。如果只需要清零,memset(C 风格)也能做到,但 fill 对任意类型都适用,更通用、更安全。
③ replace —— 替换

把区间内所有等于某个值的元素,统一替换成另一个值。

C++ · replace 批量替换
1vector<int> v = {1, 2, 3, 2, 4};
2replace(v.begin(), v.end(), 2, 99);
3// v 变成 {1, 99, 3, 99, 4}
💡
如果只想替换满足某个条件(而不是精确等于某个值)的元素,可以用 replace_if,第三个参数换成一个返回 bool 的判断函数,比如 replace_if(v.begin(), v.end(), [](int x){ return x < 0; }, 0) 把所有负数替换成 0。
④ unique —— 去重(需先排序)

unique连续重复的元素只保留第一个,多余的"挤"到区间末尾,并返回新的"有效末尾"位置——但它不会真正删除元素,容器大小不变,需要配合 erase 才能真正缩短容器。

v = {1, 2, 2, 3, 3, 3, 4};unique 之后再 erase
原数组
1
2
2
3
3
3
4
unique() 之后:前段是去重结果,后段是被"挤"出来的脏数据
1
2
3
4
3
3
4
erase(new_end, v.end()) 之后
1
2
3
4
unique 返回的迭代器指向新末尾(绿色区域之后),灰色虚线格子是残留的脏数据,必须用 erase 删掉才算真正去重完成。
C++ · unique + erase 完整去重
1vector<int> v = {1, 2, 2, 3, 3, 3, 4};
2// unique 把重复元素移到末尾,返回新末尾的迭代器
3auto new_end = unique(v.begin(), v.end());
4v.erase(new_end, v.end()); // 真正删除多余元素
5// v 变成 {1, 2, 3, 4}
⚠️
unique 只移除连续重复的元素。如果元素是分散的(比如 {1, 2, 1, 3, 1}),unique 不会把三个 1 都去掉——需要sortunique,让相同的元素先挨在一起,才能正确去重。这是竞赛里"排序去重"的标准三连招:sortuniqueerase