
本文介绍一种安全、可靠的字符串自动换行算法:在不超过指定宽度的前提下,将文本按单词边界进行分割,避免在单词中间截断,适用于控制台输出、文本渲染等场景。
本文介绍一种安全、可靠的字符串自动换行算法:在不超过指定宽度的前提下,将文本按单词边界进行截断,避免在单词中间截断,适用于控制台输出、文本渲染等场景。
实现“在指定字符数处换行,但必须在最近的空格处截断”这一需求,关键在于避免硬性按索引切分,而应采用滑动窗口式扫描+贪心截取策略。原始代码存在多个根本性问题:
- 循环从 pos = 20 递减到 0,导致对同一输入多次匹配空格并重复打印;
- input.substring(pos+1, 21) 硬编码长度 21,超出子串实际范围,极易抛出 StringIndexOutOfBoundsException;
- 未处理剩余文本(如第三行 "I need some help"),逻辑不完整。
✅ 正确思路是:
- 维护起始位置 startPos;
- 每次尝试在 startPos + maxWidth 处向左查找第一个空格;
- 若找到,则在此处分割;若未找到(即当前段无空格,如超长单词),则强制在 startPos + maxWidth 处截断;
- 更新 startPos,继续处理剩余部分,直至字符串耗尽。
以下是健壮、可直接运行的 Java 实现:
import java.util.Scanner;
public class WordWrap {
public static void wordWrap(String text, int maxWidth) {
if (text == null || text.isEmpty() || maxWidth startPos; i--) {
if (text.charAt(i - 1) == ' ') {
breakPos = i - 1;
break;
}
}
// 若未找到空格(如连续长单词),则强制在 maxWidth 处截断
if (breakPos == -1) {
breakPos = endPos;
}
System.out.println(text.substring(startPos, breakPos).stripTrailing());
startPos = breakPos + 1; // 跳过空格
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Please input a sentence: ");
String input = scanner.nextLine();
wordWrap(input, 20);
scanner.close();
}
}
? 运行示例:
输入:"Hello there, I am doing some coding, I need some help"
输出:
Hello there, I am doing some coding, I need some help
⚠️ 注意事项:
- stripTrailing()(Java 11+)用于清除行尾冗余空格,若使用低版本 JDK,可用 replaceAll("\s+$", "") 替代;
- 对于含制表符、换行符等空白字符的复杂文本,建议先标准化空白(如 text.replaceAll("\s+", " "));
- 若需支持 Unicode 字符(如中文、Emoji),注意 String.length() 返回的是 UTF-16 代码单元数,非真实字数;严格场景建议使用 java.text.BreakIterator 进行语言感知分词;
- 本算法时间复杂度为 O(n×w),其中 w 为最大行宽,在常规文本中性能优异。
该方案兼顾简洁性与鲁棒性,既解决了原始代码的逻辑缺陷,又提供了清晰可扩展的封装接口,可轻松集成至日志格式化、CLI 工具或轻量级文本渲染模块中。










