这是一道很有意思的题,它将教会我们如何拆分一个整数的各个数位,题目是这样的:
将一个整数中的数字顺序反转,例如:
x = 123,return 321;
x = -123,return -321;
那么如何对一个数字反转呢,你可能会想到将数字转化为字符串,然后翻转字符串,再将字符串转换回数字;这样做可行,但是太麻烦,我们说整数是可以直接反转的,只要我们将它的每一位拆出来就可以了,那么如何将一个整数的各个位拆分出来呢?
可以借助整数除法操作(/)和取模操作(%),下面拿123举例:
123 / 10 = 12, 123 % 10 = 3;
12 / 10 = 1, 12 % 10 = 2;
1 / 10 = 0, 1 % 10 = 1;
由此可见,对一个整数依次对10取模即可将每一位的数字拆分出来;然后只需要这样合并:(3 * 10 + 2) * 10 + 1 = 321;
很简单吧,不过要注意啦,越简单的问题越需要注意,这题就有一些细节,题中所给的整数是一个32位的带符号整数,那么它能表示的最大范围是-2147483648~2147483647,显然我们在反转一个数的时候有可能会越界,那么如何处理越界问题就变得很重要;
当发生越界的时候,程序并不会终止,而是转回下界开始,用一个范围内的数字表示,那么我们就不能与INT_MAX进行比较来确定是否越界,先来看一下代码:
class Solution {
public:
int reverse(int x)
{
int rev = 0;
while(x)
{
int temp = rev * 10 + x % 10;
//判断翻转结果是否越界,如果越界,则返回0
if(temp / 10 != rev) return 0;
rev = temp;
x /= 10;
}
return rev;
}
};
可以看到我们使用了这样一个语句来判断:
int temp = rev * 10 + x % 10;
if(temp / 10 != rev) return 0;
我们知道,一旦发生了越界(假设越界的结果可以表示为正确值):
temp = INT_MIN + temp - INT_MAX = temp - 2 * INT_MAX - 1;
temp / 10 = rev - (2 * INT_MAX + 1) / 10;
如果没有越界:
temp = rev * 10 + x % 10;
temp / 10 = rev;
可以看出发生越界的话,temp / 10的结果会和没有发生越界时不一样,那么我们就可以利用这一点来判断,一旦越界,返回0;