
本文介绍如何对任意长度的字符串生成全部循环移位结果——即从每个索引开始截取至末尾,再拼接开头至该索引前的字符,形成 n 个等长旋转字符串。
本文介绍如何对任意长度的字符串生成全部循环移位结果——即从每个索引开始截取至末尾,再拼接开头至该索引前的字符,形成 n 个等长旋转字符串。
在 Java 中,要为一个字符串 s(如 "13579")生成其所有 循环左移(circular rotations) 形式的子串(共 n = s.length() 个),核心思路是:对每个起始索引 i(0 ≤ i < n),构造新字符串 s.substring(i) + s.substring(0, i)。这种方式天然支持任意长度、任意内容的字符串,且无索引越界风险。
✅ 推荐实现(简洁、安全、通用)
import java.util.Scanner;
public class StringRotations {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入字符串:");
String s = sc.nextLine().trim();
if (s.isEmpty()) {
System.out.println("输入为空,退出。");
return;
}
int n = s.length();
System.out.println("所有循环移位结果(共 " + n + " 个):");
for (int i = 0; i < n; i++) {
// 从索引 i 开始:后半段 + 前半段
String rotated = s.substring(i) + s.substring(0, i);
System.out.println(rotated);
}
}
}运行示例:
输入 "13579",输出:
13579 35791 57913 79135 91357
⚠️ 注意事项与常见误区
- 避免 StringIndexOutOfBoundsException:原问题中手动维护索引并多次拼接易出错(如 j++ 超出范围、负索引等)。substring() 方法在 Java 中对边界有严格校验(beginIndex ≤ endIndex ≤ length),但只要按 i ∈ [0, n] 调用,s.substring(i) 和 s.substring(0,i) 均合法(当 i==0 时,substring(0,0) 返回空字符串;当 i==n 时,substring(n) 也返回空字符串)。
- 不推荐数字运算模拟(如 GeeksforGeeks 示例):该方案仅适用于纯数字字符串且需转为整数处理,存在整数溢出风险(如 "12345678901234567890" 超出 long 范围),且无法处理 '0' 开头或含非数字字符的字符串(如 "00123" → 123 会丢失前导零)。字符串操作才是通用解法。
- 性能说明:substring() 在 Java 9+ 中为 O(1) 时间(共享底层 char[]),空间复杂度为 O(n²),因需存储 n 个长度为 n 的字符串;若仅需逐行打印(而非保存),空间可优化至 O(n)。
✅ 进阶:封装为工具方法
public static List<String> getAllRotations(String s) {
if (s == null) return Collections.emptyList();
int n = s.length();
List<String> rotations = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
rotations.add(s.substring(i) + s.substring(0, i));
}
return rotations;
}此方法便于复用,支持空/null 安全校验,并返回不可变列表结构。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
总之,利用 substring 的天然循环语义,配合简单 for 循环,即可健壮、清晰、高效地解决任意字符串的全旋转生成需求——无需复杂数学推导,亦无越界隐患。

















