如何检查数字是否是回文?
任何语言.任何算法.(除了使数字成为字符串然后反转字符串的算法).
对于任何给定的数量:
n = num;
rev = 0;
while (num > 0)
{
dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}
如果n == rev
那时num
是回文:
cout << "Number " << (n == rev ? "IS" : "IS NOT") << " a palindrome" << endl;
这是项目欧拉问题之一.当我在Haskell中解决它时,我完全按照你的建议,将数字转换为字符串.然后检查该字符串是否为pallindrome是微不足道的.如果它表现得足够好,那为什么还要把它变得更复杂呢?作为一个pallindrome是一个词汇属性而不是数学属性.
def ReverseNumber(n, partial=0):
if n == 0:
return partial
return ReverseNumber(n // 10, partial * 10 + n % 10)
trial = 123454321
if ReverseNumber(trial) == trial:
print("It's a Palindrome!")
仅适用于整数.从问题陈述中不清楚是否需要考虑浮点数或前导零.
在大多数具有微不足道问题的答案之上,int变量可能会溢出.
请参阅http://leetcode.com/2012/01/palindrome-number.html
boolean isPalindrome(int x) {
if (x < 0)
return false;
int div = 1;
while (x / div >= 10) {
div *= 10;
}
while (x != 0) {
int l = x / div;
int r = x % 10;
if (l != r)
return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}
int is_palindrome(unsigned long orig)
{
unsigned long reversed = 0, n = orig;
while (n > 0)
{
reversed = reversed * 10 + n % 10;
n /= 10;
}
return orig == reversed;
}
将每个数字推入堆栈,然后将其弹出.如果前后相同,那就是回文.
我没有注意到任何使用没有额外空间解决这个问题的答案,也就是说,我看到的所有解决方案都使用了字符串,或者使用另一个整数来反转数字或其他一些数据结构.
虽然像Java这样的语言会在整数溢出上回转,但这种行为在像C这样的语言中是未定义的.[ 尝试在Java中反转2147483647(Integer.MAX_VALUE) ]解决方法可能是使用long或者东西,但在风格上,我不太喜欢那种方法.
现在,回文数字的概念是该数字应该向前和向后读取相同的数字.大.使用此信息,我们可以比较第一个数字和最后一个数字.特技是,对于第一个数字,我们需要数字的顺序.比方说,12321.将它除以10000可以得到前导1.尾随1可以通过将模数取为10来检索.现在,将其减少到232 (12321 % 10000)/10 = (2321)/10 = 232
.现在,10000需要减少2倍.所以,现在转到Java代码......
private static boolean isPalindrome(int n) {
if (n < 0)
return false;
int div = 1;
// find the divisor
while (n / div >= 10)
div *= 10;
// any number less than 10 is a palindrome
while (n != 0) {
int leading = n / div;
int trailing = n % 10;
if (leading != trailing)
return false;
// % with div gets rid of leading digit
// dividing result by 10 gets rid of trailing digit
n = (n % div) / 10;
// got rid of 2 numbers, update div accordingly
div /= 100;
}
return true;
}
根据Hardik的建议编辑,以涵盖数字中有零的情况.
在Python中,有一种快速,迭代的方式.
def reverse(n):
newnum=0
while n>0:
newnum = newnum*10 + n % 10
n//=10
return newnum
def palindrome(n):
return n == reverse(n)
这也可以防止递归的内存问题(如Java中的StackOverflow错误)
我知道的最快方法:
bool is_pal(int n) {
if (n % 10 == 0) return 0;
int r = 0;
while (r < n) {
r = 10 * r + n % 10;
n /= 10;
}
return n == r || n == r / 10;
}
只是为了好玩,这个也可以。
a = num;
b = 0;
if (a % 10 == 0)
return a == 0;
do {
b = 10 * b + a % 10;
if (a == b)
return true;
a = a / 10;
} while (a > b);
return a == b;
除了使数字成为一个字符串,然后反转字符串.
为何解雇该解决方案?它易于实现和可读.如果你被问到手边没有计算机是否2**10-23
是十进制回文,你肯定会用十进制写出它来测试它.
至少在Python中,口号'字符串操作比算术慢'实际上是假的.我将Smink的算术算法与简单的字符串反转进行了比较int(str(i)[::-1])
.速度没有显着差异 - 它发生了字符串反转的速度略快.
在低级语言(C/C++)中,口号可能会成立,但有一个可能存在大量溢出错误.
def reverse(n):
rev = 0
while n > 0:
rev = rev * 10 + n % 10
n = n // 10
return rev
upper = 10**6
def strung():
for i in range(upper):
int(str(i)[::-1])
def arithmetic():
for i in range(upper):
reverse(i)
import timeit
print "strung", timeit.timeit("strung()", setup="from __main__ import strung", number=1)
print "arithmetic", timeit.timeit("arithmetic()", setup="from __main__ import arithmetic", number=1)
结果以秒为单位(越低越好):
串行1.50960231881
算术1.69729960569