LeetCode | Reverse Integer(翻转整数)


题目:

Reverse digits of an integer.

Example1: x = 123, return 321
Example2: x = -123, return -321

click to show spoilers.

Have you thought about this?

Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!

If the integer’s last digit is 0, what should the output be? ie, cases such as 10, 100.

Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?

Throw an exception? Good, but what if throwing an exception is not an option? You would then have to re-design the function (ie, add an extra parameter).

题目不难,就是要你将整数反转显示。但是里面的问题很多,关键在于能不能将问题考虑全面。

在《剑指offer》上的面试题12:打印1到最大的n位数(这个里面只写了一种方法,书中还有另一种),也是一道数字越界的问题,通常很好的做法是设置一个数组来表示每一位。看到网上有很多人用其他方法,但是在我这里完全不能运行……也不知道什么原因。

题目中的提示信息:是否考虑了最后的若干位为0的情况;当越界了怎么办?

这些都是必须要考虑的情况,当然根据处理方法不同,正如我下面的,不存储0,但是如果输入就是0的情况,就需要另外处理了。这也是要考虑的方面。

对于将负数转化成正数,我们必须用unsigned int,那样temp才是正数,后面的运算才成立。虽然这时temp在机器中的二进制和n一样,但是temp被解析成正数。另一方面,当我们输出信息的时候,%d是以int方式输出,即使你的变量为unsigned,也可能输出成负数;同理%u以unsigned方式输出,即使你的int变量为负数!

另外,很有价值的文章补码的溢出判断与检测方法 以及 int类型取值范围

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void ReverseInteger(int n);

int main(void)
{
    int n;

    while(scanf("%d",&n) == 1){
        ReverseInteger(n);
    }

    return 0;
}

void ReverseInteger(int n)
{
    if(n==0){
        printf("0\n");
        return ;
    }

    int flag = 0;
    int arr[32] = {0};
    int len = 0;
    int remainder;
    unsigned int temp = (unsigned int)n;  //必须定义unsigned,如果为int型,对于-2147483648来说,即使取temp = -n;temp为-2147483648,以负数来表示
                            //但打印输出的时候,用%d统统解释成int型,即使变量为unsigned;同理%u解释成unsigned,即使变量为int

    if(n < 0){
        flag = 1;
        temp = (unsigned int)(-n);  //要用强制类型转换
    }
    while(temp > 0){
        remainder = temp % 10;
        temp /= 10;
        if(remainder || arr[0] != 0){
            arr[len] = remainder;
            len++;
        }
    }
    if(flag)
        printf("-");
    for(int i = 0;i < len;++i)
        printf("%d",arr[i]);
    printf("\n");
}

注意:

这道题可参考:数值的整数次方。那个地方也用到了将负数转化成正数的问题。正数转化为负数,直接加个负号即可。但负数表示的范围比正数大一,当碰到边界的时候,就会出问题。我们必须用unsigned int无符号类型来存储。并且要将n或-n强制类型转换。

代码中的temp已经是正数了,用%d打印将解析成负数(只对最大负数-2147483648来说解析成负数),用%u将解析成无符号数。其解析的都是二进制数。不管原数据是什么。比如对-1用%u打印,将变为4294967295。


点赞