字符串递增函数异常排查:CodeWars报NumberFormatException本地正常
问题排查与解决方案
异常原因
1. 整数类型范围限制
代码中处理非纯数字字符串的末尾数字时,使用Integer.parseInt(sec)转换数字字符串,但Integer的取值范围仅为-2^31至2^31-1(约±21亿)。当输入的末尾数字字符串长度超过10位(如测试用例中的"1712031362069931272877416673"),远超出Integer的最大容量,直接触发NumberFormatException。
2. 格式化语法错误(隐性问题)
纯数字分支中,使用String.format("%0"+str.length()+"d", b.add(BigInteger.valueOf(1))),但%d格式符仅支持int/long等基本整数类型,无法直接接收BigInteger对象,会触发IllegalFormatConversionException,部分环境下可能未暴露。
修复后的代码
将所有数字处理逻辑统一使用BigInteger,避免类型范围限制,同时修正前导零处理逻辑:
import java.math.BigInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { System.out.println(incrementString("foo001")); System.out.println(incrementString("33275375531813209960")); System.out.println(incrementString("0000004617702678077138438340108")); System.out.println(incrementString("1712031362069931272877416673")); System.out.println(incrementString("foo099")); } public static String incrementString(String str) { if (str.isEmpty()) { return "1"; } // 匹配前缀(非数字或空)和末尾数字(可空) Pattern pattern = Pattern.compile("(.*?)([0-9]*)$"); Matcher matcher = pattern.matcher(str); if (matcher.matches()) { String prefix = matcher.group(1); String numStr = matcher.group(2); if (numStr.isEmpty()) { // 无末尾数字,直接追加1 return str + "1"; } else { // 用BigInteger处理超长数字递增 BigInteger num = new BigInteger(numStr); BigInteger newNum = num.add(BigInteger.ONE); String newNumStr = newNum.toString(); int originalLength = numStr.length(); // 补全前导零以保持原位数 StringBuilder result = new StringBuilder(prefix); int zerosToAdd = originalLength - newNumStr.length(); if (zerosToAdd > 0) { result.append("0".repeat(zerosToAdd)); } result.append(newNumStr); return result.toString(); } } return ""; } }
修复说明
- 简化正则逻辑:使用
(.*?)([0-9]*)$直接捕获前缀和末尾数字,无需区分纯数字与非纯数字场景,逻辑更统一。 - 统一数字处理:全程使用
BigInteger,彻底解决超长数字的范围限制问题。 - 手动补前导零:避免
String.format的类型兼容问题,直接计算并补充所需前导零,保证原位数不变。
内容的提问来源于stack exchange,提问作者lvvl
相关产品推荐
相关产品推荐

