std::rotate实现循环左移的原理是将区间划分为[first, middle)和[middle, last)两段,交换其顺序;左移k位即取middle = first + k(需先对k取模并处理边界)。

std::rotate 实现循环左移的原理是什么
std::rotate 并不直接区分“左移”或“右移”,它只是把迭代器范围划分为三段:[first, middle)、[middle, last),然后将前两段交换位置(即把 [middle, last) 拼到前面,[first, middle) 拼到后面)。所以循环左移 k 位,等价于以 begin() + k 为 middle 调用 std::rotate。
注意:k 必须对容器大小取模,否则越界 —— std::rotate 不做边界检查,传入非法 middle 迭代器会导致未定义行为。
常见错误现象:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 传入
vec.begin() + k但k >= vec.size()→ 崩溃或乱序 - 误用
std::rotate(vec.begin(), vec.begin() + k - 1, vec.end())(少移一位) - 对空容器或单元素容器未提前判断,虽不崩溃但逻辑易错
怎么安全地左移 k 位(含边界处理)
关键就是先归一化 k:用 k % vec.size(),再处理 size 为 0 或 1 的情况(此时无需旋转)。
立即学习“C++免费学习笔记(深入)”;
template <typename Container>
void left_rotate(Container& c, size_t k) {
if (c.empty()) return;
k = k % c.size();
if (k == 0) return;
std::rotate(c.begin(), c.begin() + k, c.end());
}使用场景:数组重排、滑动窗口初始化、环形缓冲区模拟。
性能影响:std::rotate 是线性时间、原地操作,比手动拷贝高效;在 std::vector 上是 O(n),且缓存友好。
和 std::shift_left / 手动拷贝比有什么区别
std::shift_left(C++20)只支持「向左平移并丢弃溢出元素」,不是循环移位,不能替代 std::rotate。
手动用 std::copy 拆两段再拼,代码更长、易出错、且可能额外分配临时空间。
参数差异:
-
std::rotate(first, middle, last):middle 是新序列的起点,即原 [middle, last) 要移到最前 - 循环左移 k:middle = first + k
- 循环右移 k:等价于左移
n - k % n,即 middle = first + n - k % n
容易被忽略的兼容性细节
std::rotate 要求迭代器至少是双向迭代器,所以它不能用于 std::forward_list(只有前向迭代器)或某些自定义流式容器。
在 std::list 上,std::rotate 是常数时间(仅改指针),但在 std::vector 或 std::deque 上仍是线性时间(需移动元素)。
如果你在写泛型代码,别假设所有容器 rotate 都快 —— 具体复杂度得看容器类型。

















