palindromic number或数字回文是一个“对称”数字,如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?
答案 0 :(得分:27)
恢复你的推理。不要试图找到这些数字,而是创建它们。 您可以简单地取任何数字并对其进行镜像(总是长度均匀)并且对于相同的数字,只需在它们之间添加0..9(对于具有奇数长度的数字)。
答案 1 :(得分:15)
public static Set<Integer> allPalindromic(int limit) {
Set<Integer> result = new HashSet<Integer>();
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;
}
答案 2 :(得分:3)
有一种蛮力方法,你循环遍历所有数字并检查它们是否是回文。要检查,请反转数字并进行比较。复杂性应为O(n log10(n))。 [不是log10()很重要,但为了完整起见。 ]
另一种是根据数字生成回文。假设您必须生成5位数的回文,它们的形式为ABCBA,所以只需循环0-9并填充所有位置。现在,如果您产生低于10 ^ 4的回文,则产生1,2,3和4位数的回文。
我写了快速(和肮脏)的C ++代码来测试两种算法的速度(8位数的回文)。 蛮力:Ideone.(3.4s) 更好的算法:Ideone.(0s)
我删除了print语句,因为Ideone不允许在输出中使用这个大数据。
在我的电脑上,时间是:
Brute force:
real 0m7.150s
user 0m7.052s
Better algorithm:
real 0m0.024s
user 0m0.012s
我知道您已经将语言称为Java,但我不了解Java,这些代码只是向您展示算法之间的差异,您可以编写自己的Java代码。
PS:我已经用蛮力测试了我的代码8位数的回文,不能确定它是否对8位以上产生错误,尽管使用的方法是一般的。此外,我本来希望在评论中提供代码链接,因为已经提到了正确的方法,但我没有所需的权限。
答案 3 :(得分:2)
一种方法是简单地迭代所有数字,并检查每个数字:它是否是回文,如下:
public static boolean isPalindrome(Integer x) {
String s = x.toString();
int len = s.length();
for (int i = 0;i<len;i+=2) {
if (s.charAt(i) != s.charAt(len-i-1)) return false;
}
return true;
}
public static void main(String[] args) {
int N = 10000;
for (Integer x = 0;x<N;x++) {
if (isPalindrome(x)) System.out.println(x);
}
}
答案 4 :(得分:1)
蛮力方法:从1 ... 10000创建一个foreach循环并测试约束。更简单的是,将数字转换为字符串,将其反转并将其与原始值进行比较。这是低效率和蹩脚的。
更好的方法:考虑回文模式。考虑到回文的不同可能性,取决于数字的长度。现在提供一种生成给定长度的回文的方法。 (我不会这样做,因为这显然是家庭作业。)
答案 5 :(得分:1)
类似于下面的循环可用于打印回文数:
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);
}
}
}
答案 6 :(得分:0)
我在C#中编写这些方法可能会有所帮助。 main方法构建了一个包含给定位数的所有回文数的确定列表。它的快速和评论贯穿其中,以帮助解释我使用过程。
我还提供了一些支持方法,包括快速回文测试,值得指出的是pow10 [x]是10的幂数组,以进一步提高速度。
public static List<ulong> GetPalindromicNumbers(ulong digits = 3)
{
List<ulong> result = new List<ulong>(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);
}
/// <summary>
/// Reverses the digits in a number returning it as a new number. Trailing '0's will be lost.
/// </summary>
/// <param name="n">The number to reverse.</param>
/// <param name="radix">The radix or base of the number to reverse.</param>
/// <returns>The reversed number.</returns>
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);
}
/// <summary>
/// Concaternates the specified numbers 'a' and 'b' forming a new number 'ab'.
/// </summary>
/// <example>If a = 1234 and b = 5678 then Concat(a,b) = 12345678.</example>
/// <param name="a">The first number.</param>
/// <param name="b">The second number.</param>
/// <returns>The concaternated number 'ab'.</returns>
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);
}
/// <summary>
/// Evaluate whether the passed integer is a palindrome in base 10 or not.
/// </summary>
/// <param name="n">Integer to test.</param>
/// <returns>True - Palindrome, False - Non palindrome.</returns>
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);
}
答案 7 :(得分:0)
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);