如何找出所有回文数字

回文数字或数字回文是像16461这样的“对称”数字,当其数字反转时保持相同。

术语回文来自回文,它指的是像转子一样的单词,在其字母的反转下保持不变。

第一个回文数字(十进制)是:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, ... 

如何查找下面的所有回文数字,比如10000?

生成所有回文到特定限制。

 public static Set allPalindromic(int limit) { Set result = new HashSet(); for (int i = 0; i <= 9 && i <= limit; i++) result.add(i); boolean cont = true; for (int i = 1; cont; i++) { StringBuffer rev = new StringBuffer("" + i).reverse(); cont = false; for (String d : ",0,1,2,3,4,5,6,7,8,9".split(",")) { int n = Integer.parseInt("" + i + d + rev); if (n <= limit) { cont = true; result.add(n); } } } return result; } 

测试回文性

使用字符串

 public static boolean isPalindromic(String s, int i, int j) { return j - i < 1 || s.charAt(i) == s.charAt(j) && isPalindromic(s,i+1,j-1); } public static boolean isPalindromic(int i) { String s = "" + i; return isPalindromic(s, 0, s.length() - 1); } 

使用整数

 public static boolean isPalindromic(int i) { int len = (int) Math.ceil(Math.log10(i+1)); for (int n = 0; n < len / 2; n++) if ((i / (int) Math.pow(10, n)) % 10 != (i / (int) Math.pow(10, len - n - 1)) % 10) return false; return true; } 

恢复你的推理。 不要试图找到这些数字,而是创建它们。 您可以简单地取任何数字并对其进行镜像(总是长度均匀)并且对于相同的数字,只需在它们之间添加0..9(对于具有奇数长度的数字)。

有一种蛮力方法,你循环遍历所有数字,并检查它们是否是回文。 要检查,请反转数字并进行比较。 复杂性应为O(n log10(n))。 [不是log10()很重要,但为了完整起见。 ]

另一种是根据数字生成回文。 假设您必须生成5位数的回文,它们的forms为ABCBA,所以只需循环0-9并填充所有位置。 现在,如果您产生低于10 ^ 4的回文,则产生1,2,3和4位数的回文。

我写了快速(和脏)C ++代码来测试两种算法的速度(8位数回文)。 蛮力: Ideone。 (3.4s)更好的算法: Ideone。 (0)

我删除了print语句,因为Ideone不允许输出中的这个大数据。

在我的电脑上,时间是:

 Brute force: real 0m7.150s user 0m7.052s Better algorithm: real 0m0.024s user 0m0.012s 

我知道您已经将语言称为Java,但我不了解Java,这些代码只是向您展示算法之间的区别,您可以编写自己的Java代码。

PS:我已经用蛮力测试了我的代码8位数的回文,不能确定它是否对8位以上产生错误,尽管使用的方法是通用的。 此外,我本来希望提供注释中的代码链接,因为已经提到了正确的方法,但我没有所需的权限。

一种方法是简单地迭代所有数字,并检查每个数字:它是否是一个综合症,如下:

 public static boolean isPalindrome(Integer x) { String s = x.toString(); int len = s.length(); for (int i = 0;i 

蛮力方法:从1 … 10000创建一个foreach循环并测试约束。 更简单的是,将数字转换为字符串,将其反转并将其与原始值进行比较。 这是低效率和跛脚的。

更好的方法:考虑回文模式。 考虑到回文的不同可能性,取决于数字的长度。 现在提供一种生成给定长度的回文的方法。 (我不会这样做,因为它显然是家庭作业。)

类似于下面的循环可用于打印回文数:

 for(int i = 1; i <= 9; i++) { for(int j = 0; j <= 9; j++) { for(int k = 0; k <= 9; k++) { System.out.println("" + i + j + k + j + i); } } } 

我在C#中编写了这些方法,可能会有所帮助。 main方法构建一个包含给定位数的所有回文数的确定列表。 它的快速和评论贯穿其中,以帮助解释我使用过程。

我还提供了一些支持方法,包括快速回文测试,值得指出的是pow10 [x]是10的幂数组,以进一步提高速度。

  public static List GetPalindromicNumbers(ulong digits = 3) { List result = new List(1000); ulong limit = pow10[digits] - 1; // Add the palindromes 1 to 9 for ( ulong b = 1; b < 10; b++ ) result.Add( b ); ulong pow = 10; // Used to limit the creation of odd and even palindromes between powers of 10 ulong a = 1; // Working value which is used to set the next set of digits for abc ulong palindrome = 9; while ( palindrome < limit ) { // Build even digit palindromes of the form abc + cba where abc is any number and cba is the same number with its digits reversed while ( a < pow ) { // If 'abc' has trailing 0s they will be lost if we try to reverse it. We need to overcome this sop we check for trailing 0's // and add them to abc. eg if abc starts at 100, abc becomes 10000 and cba becomes 1 which when joined correctly forms 100001 ulong abc = a; ulong cba = a; while ( cba % 10 == 0 ) { abc *= 10; cba /= 10; } palindrome = MathExt.Concat( abc , MathExt.ReverseDigits( cba ) ); result.Add( palindrome ); // Add palindromes of the form abc + cba a++; } // Build odd digit palindromes of the form lhs + b + rhs where lhs is any number and rhs is the same number with its digits reversed a /= 10; if ( palindrome == limit ) break; // Check to see if we have the required palindromic numbers while ( a < pow ) { // Handle the special case of when b = 0 // Increase leftside by a factor of 10 for each trailing zero as these 0s will be lost when the leftside is reversed // This approach does away with the need to convert numbers with trailing zeros to strings before they are reversed. ulong lhs = a; ulong rhs = a; while ( rhs % 10 == 0 ) { lhs *= 10; rhs /= 10; } palindrome = MathExt.Concat( lhs * 10, MathExt.ReverseDigits( rhs ) ); // Multiplying the lhs by 10 is equivalent to adding b == 0 result.Add( palindrome ); // Add numbers of the form aaa + 0 + aaa lhs = a; for ( ulong b = 1; b != 10; b++ ) { rhs = a * 10 + b; // Adding b before we reverse guarantees that there is no trailing 0s palindrome = MathExt.Concat( lhs, MathExt.ReverseDigits( rhs ) ); // Works except when b == 0 result.Add( palindrome ); // Add numbers of the form aaa + b + aaa } a++; } pow *= 10; // Each pass of the outer loop add an extra digit to aaa } return (result); } ///  /// Reverses the digits in a number returning it as a new number. Trailing '0's will be lost. ///  /// The number to reverse. /// The radix or base of the number to reverse. /// The reversed number. static public ulong ReverseDigits( ulong n, uint radix = 10 ) { // Reverse the number ulong result = 0; do { // Extract the least significant digit using standard modular arithmetric result *= radix; result += n % radix; n /= radix; } while ( n != 0 ); return (result); } ///  /// Concaternates the specified numbers 'a' and 'b' forming a new number 'ab'. ///  /// If a = 1234 and b = 5678 then Concat(a,b) = 12345678. /// The first number. /// The second number. /// The concaternated number 'ab'. public static ulong Concat( this ulong a, ulong b ) { // Concaternate the two numbers by shifting 'a' to the left by the number of digits in 'b' and then adding 'b' return (a * pow10[NumberOfDigits( b )] + b); } ///  /// Evaluate whether the passed integer is a palindrome in base 10 or not. ///  /// Integer to test. /// True - Palindrome, False - Non palindrome. static public bool IsPalindrome( this ulong n ) { uint divisor = NumberOfDigits( n ) - 1; do { // Extract the most and least significant digits of (n) ulong msd = n / pow10[divisor]; ulong lsd = n % 10; // Check they match! if ( msd != lsd ) return (false); // Remove the msd and lsd from (n) and test the next most and least significant digits. n -= msd * pow10[divisor]; // Remove msd n /= 10; // Remove lsd divisor -= 2; // Number has reduced in size by 2 digits } while ( n != 0 ); return (true); } 
 import Queue import copy def printPalindromesTillK(K): q = Queue.Queue(K); for i in range(0, 10): q.put(str(i)); q.put(str(i) + str(i)); while(not q.empty()): elem = q.get(); print elem; for i in range(1, 10): item = str(i) + elem + str(i); if int(item) <= K: q.put(item); print printPalindromesTillK(10000);