TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
自然数中有一类数被称为回文数。回文数就是一个数的两边对称,如11,121,1221,9339,30203等 等。回文数本身倒也没有什么奇特。不过人们发现大多数的自然数,如果把它各位数字的顺序倒置,再与原数相加,将得数再按上述步骤进行,经过有限的步骤后必能得到一个回文数:
如: 95+59=154
154+451=605
605+506=1111 1111就是一个回文数。
又如: 198+891=1089
1089+9801=10890
10890+09801=20691
20691+19602=40293
40293+39204=79497 79497又是一个回文数。
是不是所有的自然数都有这个性质呢?不是。例如三位数中的196似乎用上述办法就得不到回文数。有人用计算机对196用上述办法重复十万次,仍然没有得 到回文数。但至今还没有人能用数学证明办法对这个问题下结论,所有"196问题"也成了世界性数学难题之一。经过计算,在前十万个自然数中有5996个数 就像196一样很难得到回文数。 下面的程序,从一个已知数出发,用递归调用,通过与其逆序数相加在长整型(long)范围内找回文数。如果数字太大,超出java的64位整数型,就会溢出。
public class Palindrome {
public static boolean verbose = true;
public static void main(String[] argv) {
for (int i=0; i< argv.length; i++)
try {
long l = Long.parseLong(argv);
if (l < 0) {
System.err.println(argv + " -> 太小");
System.out.println();
continue;
}
System.out.println(argv + "->" + findPalindrome(l));
System.out.println();
} catch (NumberFormatException e) {
System.err.println(argv + "-> 无效数字");
System.out.println();
} catch (IllegalStateException e) {
System.err.println(argv + "-> " + e);
}
}
/**递归调用找回文数字,直到找到为止
*/
static long findPalindrome(long num) {
if (num < 0)
throw new IllegalStateException("negative");
if (isPalindrome(num))
return num;
if (verbose)
System.out.println("Trying " + num);
return findPalindrome(num + reverseNumber(num));//将num与逆序数相加
}
/** Long.MAX_VALUE的位数 */
protected static final int MAX_DIGITS = 19;
static long[] digits = new long[MAX_DIGITS];
/** 检验数字是否是回文的 */
static boolean isPalindrome(long num) {
if (num >= 0 && num <= 9)
return true;
int nDigits = 0;
while (num > 0) {
digits[nDigits++] = num % 10;
num /= 10;
}
for (int i=0; i< nDigits/2; i++)
if (digits != digits[nDigits - i - 1])
return false;
return true;
}
static long reverseNumber(long num) {//返回num的逆序数
int nDigits = 0;
while (num > 0) {
digits[nDigits++] = num % 10;
num /= 10;
}
long ret = 0;
for (int i=0; i< nDigits; i++) {
ret *= 10;
ret += digits;
}
return ret;
}
}
[/code] 下面是程序的一次运行:
C:java>java Palindrome 145 1921 17892 -8 123a 196
Trying 145
145->686 Trying 1921
Trying 3212
1921->5335 Trying 17892
Trying 47763
Trying 84537
Trying 158085
Trying 738936
Trying 1378773
Trying 5157504
Trying 9215019
Trying 18320148
Trying 102422529
Trying 1027646730
Trying 1404113931
17892->2797227972 -8 -> 太小 123a-> 无效数字 Trying 196
Trying 887
Trying 1675
Trying 7436
Trying 13783
Trying 52514
Trying 94039
Trying 187088
Trying 1067869
Trying 10755470
Trying 18211171
Trying 35322452
Trying 60744805
Trying 111589511
Trying 227574622
Trying 454050344
Trying 897100798
Trying 1794102596
Trying 8746117567
Trying 16403234045
Trying 70446464506
Trying 130992928913
Trying 450822227944
Trying 900544455998
Trying 1800098901007
Trying 8801197801088
Trying 17602285712176
Trying 84724043932847
Trying 159547977975595
Trying 755127757721546
Trying 1400255515443103
Trying 4413700670963144
Trying 8827391431036288
Trying 17653692772973576
Trying 85191620502609247
Trying 159482241005228405
Trying 664304741147513356
Trying 1317620482294916822
Trying 3603815405135183953
Trying 7197630720180367016
196-> java.lang.IllegalStateException: negative C:java> 下面这个程序则是在更大的范围(BigInteger)内找回文数: import java.math.BigInteger;
public class PalindromeBig {
public static boolean verbose = true;
public static void main(String[] argv) {
for (int i=0; i< argv.length; i++)
try {
BigInteger l = new BigInteger(argv);
if (l.compareTo(BigInteger.ZERO) < 0) {
System.err.println(argv + " -> TOO SMALL");
continue;
}
System.out.println(argv + "->" + findPalindrome(l));
} catch (NumberFormatException e) {
System.err.println(argv + "-> INVALID");
} catch (IllegalStateException e) {
System.err.println(argv + "-> " + e);
}
}
public static BigInteger findPalindrome(BigInteger num) {
if (num.compareTo(BigInteger.ZERO) < 0)
throw new IllegalStateException("negative");
if (isPalindrome(num))
return num;
if (verbose)
System.out.println("Trying " + num);
return findPalindrome(num.add(reverseNumber(num)));
}
protected static final int MAX_DIGITS = 255;
public static boolean isPalindrome(BigInteger num) {
String digits = num.toString();
int numDigits = digits.length();
if (numDigits >= MAX_DIGITS) {
throw new IllegalStateException("too big");
}
// Consider any single digit to be as palindromic as can be
if (numDigits == 1)
return true;
for (int i=0; i< numDigits/2; i++) {
if (digits.charAt(i) != digits.charAt(numDigits - i - 1))
return false;
}
return true;
}
static BigInteger reverseNumber(BigInteger num) {
String digits = num.toString();
int numDigits = digits.length();
char[] sb = new char[numDigits];
for (int i=0; i< digits.length(); i++) {
sb = digits.charAt(numDigits - i - 1);
}
return new BigInteger(new String(sb));
}
}
[/code] 下面程序则可输出20个在long整型数范围内不能判断的数: public class PalindromeFirst {
public static void main(String[] argv) {
int numErrors = 0;
Palindrome.verbose = false;
for (int i=0; i< Long.MAX_VALUE; i++) {
try {
Palindrome.findPalindrome(i);
} catch (RuntimeException ex) {
System.out.println("Caught exception on " + i + ": " + ex);
numErrors = numErrors + 1;
if (numErrors > 20)
return;
}
}
}
}
[/code] 运行结果:
C:java>java PalindromeFirst
Caught exception on 196: java.lang.IllegalStateException: negative
Caught exception on 295: java.lang.IllegalStateException: negative
Caught exception on 394: java.lang.IllegalStateException: negative
Caught exception on 493: java.lang.IllegalStateException: negative
Caught exception on 592: java.lang.IllegalStateException: negative
Caught exception on 689: java.lang.IllegalStateException: negative
Caught exception on 691: java.lang.IllegalStateException: negative
Caught exception on 788: java.lang.IllegalStateException: negative
Caught exception on 790: java.lang.IllegalStateException: negative
Caught exception on 879: java.lang.IllegalStateException: negative
Caught exception on 887: java.lang.IllegalStateException: negative
Caught exception on 978: java.lang.IllegalStateException: negative
Caught exception on 986: java.lang.IllegalStateException: negative
Caught exception on 1495: java.lang.IllegalStateException: negative
Caught exception on 1497: java.lang.IllegalStateException: negative
Caught exception on 1585: java.lang.IllegalStateException: negative
Caught exception on 1587: java.lang.IllegalStateException: negative
Caught exception on 1675: java.lang.IllegalStateException: negative
Caught exception on 1677: java.lang.IllegalStateException: negative
Caught exception on 1765: java.lang.IllegalStateException: negative
Caught exception on 1767: java.lang.IllegalStateException: negative C:java>
源码下载:http://file.javaxxz.com/2014/10/1/065334594.zip |
|