Java实现字符串分割与降序排序:以5为分隔符实例解析
在处理结构化文本数据时,常需根据特定规则清洗数据并进行排序。本文介绍一种Java实现方案:将字符串中的指定字符(如'5')作为分隔符拆分内容,去除头部无效零值后,将得到的数字集合按降序排列。该方案结合了手动维护有序列表的插入逻辑与标准的单元测试框架,确保代码在各类边界场景下的稳定性。
需求分析与核心逻辑
目标是在一行由0-9组成的字符串中,将所有'5'视为分隔符,提取出的连续数字序列即为待处理整数。处理流程包含以下关键步骤:
- 字符串分割:利用正则表达式或内置方法将'5'替换为空格或直接分割。
- 数值转换与过滤:将分割后的子串转换为整数,同时规范‘0’开头的处理逻辑(例如“007”转为7,“000”转为0)。
- 降序排序:获取所有有效整数后,按照从大到小的顺序排列。
代码实现细节
以下代码示例展示了如何在一个静态方法 getSortNum 中完成上述逻辑。为了演示清晰,代码中直接实现了基于链表的手动插入排序,以维持列表始终有序,避免后续单独调用排序函数。
第1步:定义主处理类与参数校验
首先构建工具类,并在入口方法中对输入长度和合法性进行预判,防止无效计算。
参数说明:
- input: 源字符串,仅含数字,长度限制在1000以内。
- output: 用于存放最终结果的 StringBuilder。
import java.util.LinkedList;
public class OJ {
public static int getSortNum(final String input, final StringBuilder output) {
// 校验输入合法性
if (input == null || input.length() <= 0 || input.length() > 1000) {
return -1;
}
// ... 后续处理逻辑见第2步 ...
}
}
第2步:执行分割与逐元素有序插入
使用 String.split("5") 对原字符串切分。遍历每个片段,若不为空则尝试转为整数。为保证最终结果降序,采用插入排序思想:
从当前有序链表的尾部向前扫描,找到第一个小于新数字的位置插入。这样无需对全集二次排序。
public static int getSortNum(final String input, final StringBuilder output) {
if (input == null || input.length() <= 0 || input.length() > 1000) {
return -1;
}
// 1. 分割字符串,以 '5' 为界
String[] nums = input.split("5");
LinkedList<Integer> sortedList = new LinkedList<>();
int count = 0;
for (String numStr : nums) {
if (!numStr.isEmpty()) {
try {
// 2. 转换并检查范围 (题目要求数值不超过1亿)
int value = Integer.valueOf(numStr);
if (value > 100000000) {
return -1; // 超出规定范围
}
// 3. 维护降序插入
// 找到插入位置:从后往前找,遇到比当前值大的数停止
int k = count;
while (k > 0 && value > sortedList.get(k - 1)) {
k--;
}
// 在第 k 个位置插入,后面的元素自动后移
sortedList.add(k, value);
count++;
} catch (NumberFormatException e) {
return -1;
}
}
}
// ... 格式化输出见第3步 ...
}
第3步:格式化输出结果
遍历排序好的链表,将整数拼接为字符串。注意相邻数字间用空格分隔,首尾无多余空格。
// 4. 组装结果字符串
for (int i = 0; i < sortedList.size() - 1; i++) {
output.append(sortedList.get(i)).append(" ");
}
if (!sortedList.isEmpty()) {
output.append(sortedList.getLast());
}
output.trimToSize();
return 0;
}
测试验证策略
为了确保逻辑正确,特别是针对前导零、连续分隔符以及超大数值等边缘情况,建议使用 JUnit 进行测试。以下是几个典型的测试场景分析:
典型用例解析
- 常规混合分隔:
"1234543215555"。分割得到 ["1234", "4321", "", "", ""]。转换后为 1234, 4321。降序结果为 “4321 1234”。 - 前导零处理:
"...00005..."。分割出的 "0000" 会被Integer.valueOf()识别为 0,且保留在列表中。若全是0,则结果为单个 “0”。 - 非法超限:若某段数字转换后大于 100,000,000,函数应直接返回 -1 终止。
- 异常字符或空输入:虽然假设输入只含数字,但健壮性代码仍包含对转换异常的捕获。
JUnit 测试示例结构
开发者可参考以下结构编写断言:
期望返回值:0 表示成功,-1 表示异常。
期望输出内容:严格匹配格式化后的数字序列。
import junit.framework.Assert;
import org.junit.Test;
public class OJTest {
@Test
public void testNormalCase() {
StringBuilder out = new StringBuilder();
Assert.assertTrue(0 == OJ.getSortNum("1234543215555", out));
Assert.assertEquals("4321 1234", out.toString());
}
@Test
public void testLeadingZeros() {
StringBuilder out = new StringBuilder();
// 例子包含 0000 -> 0
Assert.assertTrue(0 == OJ.getSortNum("12345000056436567", out));
Assert.assertEquals("6436 4321 1234 0", out.toString());
}
@Test
public void testOverflowOrError() {
StringBuilder out = new StringBuilder();
// 超长或无效输入应返回错误码
// 此处模拟数值溢出或特定格式错误逻辑
// Assert.assertTrue(-1 == OJ.getSortNum("...large number...", out));
}
}
关键点总结
本实例的核心在于边读取边排序的高效思维,以及对待处理字符串中特殊占位符(分隔符)的准确识别。在实际生产环境中,若数据量极大,建议先统一转换存入数组,再使用 Arrays.sort() 配合比较器倒序排列,以提升代码可读性和运行效率。而对于嵌入式或内存受限环境,上述插入链表的方式能有效减少空间复杂度开销。
以上就是Java字符串替换分割与降序排序实现的详细内容,更多关于Java字符串处理算法的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









