最简方案是直接用std::rotate(s.begin(), s.begin() + k % s.size(), s.end()),原地O(n)左移,语义清晰、安全高效;右移转为等效左移处理;char数组需先获取真实长度并确保'\0'终止。
std::rotate 实现字符串循环左移最简方案
直接用
,别手写三步翻转——它就是为这事设计的,语义清晰、性能最优、无边界风险。
常见错误是手动计算索引 +
拼接,既易越界又生成临时对象;还有人用
循环逐字符搬,O(n) 时间还带 cache 不友好。
原地操作,时间复杂度 O(n),实际常数极小(底层用内存块移动或分段交换)
注意迭代器范围:左移 k 位,等价于把
到
这段“旋转到后面”,所以调用形式是
k 可能大于字符串长度,必须取模,否则
迭代器非法
空字符串或 k == 0 时,
安全,无需额外判断
右移怎么转成左移来处理
标准库没提供
,但右移 k 位 = 左移
位,换算后仍走
。
硬写右移逻辑容易错在模运算和方向混淆,比如把
当成右移步数直接传进
,结果是反向乱序。
立即学习
“
C++免费学习笔记(深入)
”;
右移 k 位 → 等效左移
,外层再套一次模防 k==0
更稳妥写法:先算
,再用
不要用
手动三步翻转(reverse whole → reverse first part → reverse second part),代码长、易漏边界、可读性差
char 数组 / C 风格字符串怎么安全旋转
如果操作的是
或栈上固定数组(如
),不能直接用
迭代器,得先确认长度且避免溢出。
C知道
CSDN推出的一款AI技术问答工具
下载
典型坑是把
结果当 sizeof 用,或者对未初始化内存调用
导致崩溃。
必须先获取有效长度:
,不能用
(指针下 sizeof 是 8)
旋转前确保
以
结尾,否则
后可能破坏终止符,后续
出错
推荐转成
处理再回写,或用
管理生命周期
若坚持原地操作,可用
,但需保证
有足够空间且
移动语义下 rotate 对 string 的影响
在 C++11 后支持移动,但
是原地算法,不触发分配也不调用移动构造——它只重排已有字符内存。
有人误以为
会引发 reallocation 或 copy-on-write,其实完全不会;唯一例外是 debug 模式下部分 STL 实现做迭代器调试检查,但不影响逻辑。
无论
内部用 SSO 还是堆内存,
都只改字符顺序,capacity 和 data 地址不变
如果字符串很大(几 MB),
依然高效,因为底层通常用
或分治交换,不是逐字节拷贝
别为了“性能”提前
,
不改变 size,也无需新空间
真正容易被忽略的是:旋转后字符串的
返回值仍有效,但如果你在多线程里同时读写同一
,哪怕只调
,也得加锁——它不是线程安全的操作。
std::rotatesubstrforstd::rotates.begin()s.begin() + kstd::rotate(s.begin(), s.begin() + k % s.size(), s.end())s.begin() + kstd::rotate
#include
#include
std::string s = "abcdef";
int k = 2;
std::rotate(s.begin(), s.begin() + (k % s.size()), s.end()); // 结果: "cdefab"
std::rotate_rights.size() - k % s.size()std::rotatek % s.size()std::rotate(s.size() - k % s.size()) % s.size()shift = k % s.size()std::rotate(s.begin(), s.begin() + s.size() - shift, s.end())std::reversechar*char buf[1024]std::rotatestrlenstrlensize_t len = std::strlen(s)sizeof(s)s'\0'std::rotateprintfstd::stringstd::vectorstd::rotate(&s[0], &s[k % len], &s[len])slen > 0std::stringstd::rotaterotatestd::stringstd::rotatestd::rotatememmovereserverotatec_str()std::stringrotate