如何实现覆盖所有边界的长字符串有效数字验证算法?
解决思路与代码实现
先明确从示例推导的有效数字核心规则:
- 仅允许字符:数字、单个开头的'-'、最多一个'.'
- 整数类型:无'.',长度≥1,无前导零(除非是单个"0")
- 小数类型:有且仅有一个'.',且'.'不在开头/结尾(即整数、小数部分都必须有数字);整数部分无前导零(除非是单个"0")
- 不能包含任何非法字符
以下是覆盖所有边界情况的实现代码,适配超长字符串场景(线性扫描,无溢出/精度问题):
public static boolean isValidNumber(String s) { if (s == null || s.isEmpty()) { return false; } int start = 0; // 处理开头负号 if (s.charAt(0) == '-') { start = 1; // 负号后不能为空 if (start >= s.length()) { return false; } } boolean seenDot = false; int intPartLength = 0; int fracPartLength = 0; for (int i = start; i < s.length(); i++) { char c = s.charAt(i); if (Character.isDigit(c)) { // 区分数字属于整数部分还是小数部分 if (!seenDot) { intPartLength++; } else { fracPartLength++; } } else if (c == '.') { if (seenDot) { // 存在多个小数点 return false; } seenDot = true; } else { // 非法字符直接返回false return false; } } // 处理纯整数情况 if (!seenDot) { if (intPartLength == 0) { return false; } // 长度大于1的整数不能有前导零 if (intPartLength > 1 && s.charAt(start) == '0') { return false; } } else { // 小数必须同时有整数和小数部分 if (intPartLength == 0 || fracPartLength == 0) { return false; } // 小数的整数部分长度大于1时不能有前导零 if (intPartLength > 1 && s.charAt(start) == '0') { return false; } } return true; }
验证所有测试用例
- "13" → true(合法整数)
- "3.0" → true(合法小数)
- "-7.4" → true(合法负数小数)
- "-13.5" → true(合法负数小数)
- "abc" → false(含非法字符)
- "123a" → false(含非法字符)
- "-." → false(无整数/小数部分)
- "1.0.0.1" → false(多个小数点)
- "001" → false(整数前导零)
- ".0" → false(无整数部分)
- "00.0" → false(整数部分前导零)
- "0." → false(无小数部分)
关键设计点
- 线性扫描字符串,仅用常数额外空间,适配数百万字符的超长输入
- 拆分整数/小数部分长度统计,明确区分两部分的有效性
- 针对性处理前导零问题,仅在整数部分长度>1时触发检查
- 强制小数必须同时具备整数和小数部分,避免单边为空的无效情况
内容的提问来源于stack exchange,提问作者spacecs
相关产品推荐
相关产品推荐

