如何在C++中重复vector<int>元素?含大量重复的高效实现
高效重复vector元素的实现方案
咱们先从简单场景聊起——如果只是需要重复3次,用最直观的写法就足够,代码简洁还不容易出错:
#include <vector> using namespace std; int main() { vector<int> v = {1,2,3,4,5}; const int repeat_times = 3; // 预先分配足够空间,避免vector频繁扩容 v.reserve(v.size() * repeat_times); // 循环插入原vector的元素 for (int i = 1; i < repeat_times; ++i) { v.insert(v.end(), v.begin(), v.end()); } // 现在v就是{1,2,3,4,5,1,2,3,4,5,1,2,3,4,5} return 0; }
不过如果要重复上千次(比如1000次),上面的循环要执行999次insert调用,虽然能跑,但效率还有优化空间。这时候推荐两种高效方案,根据你的元素类型来选:
方案一:指数倍增法(通用型,适合所有元素类型)
这个思路是通过每次复制当前已有的全部元素来快速扩容,比如先把vector从5个元素变成10个,再变成20个,直到接近目标长度,最后补全剩下的部分。循环次数只有log2(repeat)次(比如1000次的话,只需要循环10次左右),大幅减少了函数调用和内存拷贝的开销:
#include <vector> #include <algorithm> // 用于min函数 using namespace std; int main() { vector<int> v = {1,2,3,4,5}; const int repeat = 1000; const size_t original_len = v.size(); const size_t target_len = original_len * repeat; // 预先分配目标大小的空间,避免扩容开销 v.reserve(target_len); size_t current_len = original_len; while (current_len < target_len) { // 每次复制的长度是当前长度和剩余需要长度的较小值 size_t copy_len = min(current_len, target_len - current_len); v.insert(v.end(), v.begin(), v.begin() + copy_len); current_len += copy_len; } return 0; }
为什么这个方法高效?核心在于:
- 预先
reserve空间,彻底避免了vector多次扩容带来的内存分配和数据拷贝成本; - 大块连续内存的拷贝效率远高于多次小块拷贝,CPU缓存能更好地发挥作用;
- 循环次数极少,减少了函数调用的额外开销。
方案二:memcpy直接内存拷贝(仅适用于POD类型)
如果你的vector元素是POD类型(比如int、float、char这些简单类型,没有自定义构造/析构函数的类),可以用memcpy直接操作内存,这是效率最高的方式,因为它跳过了C++迭代器的封装,直接调用底层内存拷贝:
#include <vector> #include <cstring> // 用于memcpy using namespace std; int main() { vector<int> v = {1,2,3,4,5}; const int repeat = 1000; const size_t original_size = v.size(); const size_t target_size = original_size * repeat; // 直接resize到目标大小,分配内存(int会被默认初始化为0,但之后会被覆盖) v.resize(target_size); // 从第二个重复块开始,用memcpy拷贝原数据 for (size_t i = original_size; i < target_size; i += original_size) { memcpy(v.data() + i, v.data(), original_size * sizeof(int)); } return 0; }
⚠️ 注意:这个方法只适用于POD类型!如果是自定义类(比如带有构造函数的类),用memcpy会跳过对象的构造过程,导致未定义行为。
关键注意点
不管用哪种方法,预先分配足够的空间都是必须的——如果不做reserve/resize,vector会在元素数量超过当前容量时自动扩容,每次扩容都要重新分配内存并拷贝所有现有元素,这会带来极大的性能开销,尤其是重复上千次的时候。
内容的提问来源于stack exchange,提问作者Nick X Tsui
相关产品推荐
相关产品推荐

