Long.toString大数字高基数转换异常,求修复方案
问题修复方案
核心问题分析
你的代码出现异常的原因有三个:
Long.toString的基数限制:Java中Long.toString(long, int radix)仅支持2~36的基数,超过这个范围会默认使用10进制转换,导致高基数下的结果完全不符合预期。- 大数字溢出:如果输入数字超过
Long.MAX_VALUE(9223372036854775807),Long.parseLong会直接抛出NumberFormatException。 - 循环效率极低:从2遍历到
Integer.MAX_VALUE完全没必要,对于任意正整数N,若在2~√N范围内找不到回文基数,那么最小基数必然是N-1(此时N在该基数下表示为"11",是回文)。
修复后的代码
import java.math.BigInteger; import java.util.Scanner; public class PalindromeBase { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { String numStr = in.next(); if (numStr.equals("0")) { break; } BigInteger num = new BigInteger(numStr); System.out.println(findMinBase(num)); } in.close(); } // 判断字符串是否为回文 private static boolean isPalindrome(String s) { int left = 0; int right = s.length() - 1; while (left < right) { if (s.charAt(left) != s.charAt(right)) { return false; } left++; right--; } return true; } // 寻找最小基数 private static int findMinBase(BigInteger num) { // 特殊情况:num为1,最小基数是2(1在任何基数下都是回文,但要求B≥2) if (num.equals(BigInteger.ONE)) { return 2; } // 遍历基数2到sqrt(num) BigInteger sqrtNum = num.sqrt(); for (int base = 2; base <= sqrtNum.intValue(); base++) { String numInBase = num.toString(base); if (isPalindrome(numInBase)) { return base; } } // 若前面没找到,返回num-1(此时表示为"11",必为回文) return num.subtract(BigInteger.ONE).intValue(); } }
关键修改说明
- 改用BigInteger处理大数字:完全避免了溢出问题,且
BigInteger.toString(int radix)在2~36范围内的转换是可靠的。 - 优化输入处理:使用
in.next()逐个读取输入,直到遇到0终止,支持多行或单行输入的场景,逻辑更准确。 - 缩小循环范围:仅遍历2到√N的基数,大幅提升效率;若此范围无符合条件的基数,直接返回N-1,无需继续遍历。
- 优化回文判断:通过双指针直接比较字符串首尾字符,避免了字符串拼接的性能损耗。
内容的提问来源于stack exchange,提问作者helios
相关产品推荐
相关产品推荐

