You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何将字符串按长度≤20无生硬截断拆分为字符串数组

问题描述

现有一个存储随机地址的字符串,示例如下:

String s = "H.N.-13/1443 laal street near bharath dental lab near thana qutubsher near modern bakery saharanpur uttar pradesh 247001";

需要将该字符串拆分为字符串数组,拆分需满足两个规则:

  • 数组中每个字符串元素的长度小于等于20
  • 数组元素不能出现生硬截断,即不能从单词中间拆分导致语义断裂

错误拆分示例

如果直接按每20个字符硬截断,会得到不符合要求的结果:

"H.N.-13/1443 laal st"
"reet near bharath de"
"ntal lab near thana"
"qutubsher near moder"
"n bakery saharanpur"

预期正确输出

符合要求的拆分结果如下,每个元素长度不超过20,且无单词被截断:

"H.N.-13/1443 laal"
"street near bharath"
"dental lab near"
"thana qutubsher near"
"modern bakery"
"saharanpur"

原有代码问题

原有实现是直接按固定20字符步长截取,仅简单处理了片段开头的空格,没有按单词边界做回退截断,必然会出现单词被拆分的问题;且预先用字符串总长度除以24计算数组长度的逻辑,和实际拆分规则完全不匹配,无法得到正确结果。


正确实现方案

实现逻辑:

  1. 先将原字符串去除首尾多余空格,按空格拆分为独立单词,自动过滤连续的无效空格,从根源避免截断单词
  2. 逐一遍历单词,向当前行拼接内容:如果拼接后总长度不超过20就继续添加,超过限制就把当前已有内容存为一个数组元素,用当前单词开启新行
  3. 增加边界处理:如果单个单词本身长度就超过20,直接单独存为一行,避免死循环
  4. 遍历结束后把最后一行剩余内容存入结果集

完整可运行代码如下:

import java.util.ArrayList;
import java.util.List;

public class AddressSplitter {
    /**
     * 按指定最大长度拆分字符串,不截断单词
     * @param s 待拆分的原字符串
     * @param maxLen 每个拆分片段的最大允许长度
     * @return 拆分后的字符串数组
     */
    static String[] split(String s, int maxLen) {
        String[] words = s.trim().split("\\s+");
        List<String> result = new ArrayList<>();
        StringBuilder currentLine = new StringBuilder();

        for (String word : words) {
            // 单个单词长度超限时单独成行,避免死循环
            if (word.length() > maxLen) {
                if (currentLine.length() > 0) {
                    result.add(currentLine.toString());
                    currentLine.setLength(0);
                }
                result.add(word);
                continue;
            }

            if (currentLine.length() == 0) {
                currentLine.append(word);
            } else {
                // 计算拼接空格+新单词后的总长度
                int newLength = currentLine.length() + 1 + word.length();
                if (newLength <= maxLen) {
                    currentLine.append(" ").append(word);
                } else {
                    // 超限时先存当前行,再开新行
                    result.add(currentLine.toString());
                    currentLine.setLength(0);
                    currentLine.append(word);
                }
            }
        }

        // 存入最后一行剩余内容
        if (currentLine.length() > 0) {
            result.add(currentLine.toString());
        }

        return result.toArray(new String[0]);
    }

    public static void main(String[] args) {
        String add = "H.N.-13/1663 laal street near bharath dental lab near thana qutubsher near modern bakery";
        String city = "saharanpur";
        String state = "uttar pradesh";
        String zip = "247001";
        String s = add + " " + city + " " + state + " " + zip;
        String[] ans = split(s, 20);
        // 打印验证结果
        for (String item : ans) {
            System.out.printf("\"%s\" 长度:%d%n", item, item.length());
        }
    }
}

运行结果

执行main方法后输出如下,所有片段长度均不超过20,无单词截断问题:

"H.N.-13/1663 laal" 长度:17
"street near bharath" 长度:19
"dental lab near" 长度:15
"thana qutubsher near" 长度:20
"modern bakery" 长度:13
"saharanpur uttar" 长度:16
"pradesh 247001" 长度:14

内容的提问来源于stack exchange,提问作者Umar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:51:20