前面一节我们学习了旋转算法 rotate() 函数,读者是否还记得它的功能是什么吗?没错,该函数能够对序列进行原地循环移位操作,该操作会物理破坏原序列完整性,如果你不想这样,读者推荐使用rotate_copy()函数。那什么是rotate_copy() 函数呢?"rotate" 意为"旋转","copy" 意为"复制",从名称就能看出,这个函数不仅会旋转元素,还会将结果复制到目标序列,保持原序列不变。
rotate_copy() 函数的语法格式如下:
template< class ForwardIt, class OutputIt > OutputIt rotate_copy( ForwardIt first, ForwardIt middle, ForwardIt last, OutputIt ret );
rotate_copy(first, middle, last, ret) 函数的功能是:将区间 [first, last) 中的元素进行循环左移,使得 middle 指向的元素成为新的首元素,然后将旋转后的序列复制到以 ret 为起始位置的目标区域。与 rotate() 不同,rotate_copy() 不会修改原序列,而是创建旋转后的副本。该函数返回指向目标序列中最后复制元素的下一个位置的迭代器。比如我们有一个序列:{1, 2, 3, 4, 5},使用 rotate_copy(v.begin(), v.begin() + 2, v.end(), dest.begin()) 后,原序列保持不变,目标序列变为 {3, 4, 5, 1, 2}。
下面我们通过代码来演示 rotate_copy() 函数的实际应用:
#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>//移动迭代器
#include<string>
using namespace std;
/*rotate_copy(first, middle, last) 函数*/
void test() {
vector<char> v1{'.','c','o','m','d','o','t','c','p','p'};
vector<char> v2(v1.size());//目标容器
/*旋转前*/
cout << "v1旋转之前:";
for_each(v1.begin(), v1.end(), [](const char&c){
cout << c;
});
cout << '\n';
/*开始旋转*/
if(find(v1.begin(),v1.end(),'d')!=v1.end())//必要判断
{
rotate_copy(v1.begin(),find(v1.begin(),v1.end(),'d'),v1.end(),v2.begin()) ;//配合find()函数旋转
}
/*旋转后*/
cout << "旋转之后:\nv1=:";
for_each(v1.begin(), v1.end(), [](const char&c){
cout << c;
});
cout << '\n';
cout << "v2=:";
for_each(v2.begin(), v2.end(), [](const char&c){
cout << c;
});
}
int main(){
system("title dotcpp.com");
test();
return 0;
}编译结果如下:

观察输出我们发现,v1的".comdotcpp" 被旋转复制为v2的 "dotcpp.com",原序列v1保持不变,输出符合预期!
总结:rotate_copy() 函数提供了一个安全的序列旋转复制机制,它能够在保持原序列不变的前提下生成旋转后的副本;同时在蓝桥杯、ACM等算法竞赛上,rotate_copy() 是处理需要保留原始数据的旋转操作、多版本数据比较等问题的理想工具,是 STL 算法库中一个既实用又安全的函数。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程