[c++]关于倒转32位int整数的范围控制问题

题目来源:leetcode Reverse Integer

Given a 32-bit signed integer, reverse digits of an integer.

Example 1:            Example 2:          Example 3:

Input: 123             Input: -123         Input: 120

Output: 321          Output: -321       Output: 21

 

Note:
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

 

思路: 

  • 考虑三种情况:
    1. 数值本身就溢出。
    2. 数值将要溢出,分界在未知数与INT_MAX位数相同。
    3. 数值在安全范围内。
  • 解决方案:
    1. 先判断溢出,若溢出直接返回0
    2. 边按位比较,边倒转,判断溢出,若溢出返回0
    3. 直接倒转

前提处理:

 

1 int m=x,i=1,ten=1;//i记录位数,ten记录最高位数要*10的
2 while(m/=10){ ++i;ten*=10;}
3 if(i<10) m=reversemin(x,i,ten);
4 else m=reversemax(x,i,ten);

 

 

 

 

判断数值溢出:

1 unsigned int y = x;//扩大范围
2 if(x<0) y=-x;
3 if(y>INT_MAX) return 0;

按位比较,并倒转:

 1 int reversemax(int x,int i,int ten)
 2 {
 3     int sign=1;
 4     if(x<0) {x=-x; sign=-1;}//负数变为正数,sign还原负数
 5     int m=0,max=INT_MAX;
 6     while (i--) {
 7             int rest = x % 10;
 8             int mrest=max/ten;
 9             if(rest>mrest) return 0;//与INT_MAX按位比较,如果大于则已经溢出,返回0
10             else if(rest<mrest) break;//如果小于则进入了安全范围,跳到安全的倒转
11             m += rest * ten;//只有在相等的情况才需要进行下一次比较
12             x /= 10;
13             max=max-mrest*ten;
14             ten /= 10;
15         }
16     if(ten==0) return m*sign;
17     ++i;//最后一次循环中止时,没有操作,所以还原被删去的位数
18     
19     while (i--) {//正常倒转
20             int rest = x % 10;
21             m += rest * ten;
22             x /= 10;
23             ten /= 10;
24         }
25     return m*sign;
26     
27 }

!负数取模之后是负数,无法进行比较,所以先取正。

!判断是否倒转完,第16行,不能用位数,因为中断出来位数也减了1

直接倒转:

 

 1 int reversemin(int x, int i, int ten)
 2     {
 3         int m = 0;
 4         while (i--) {
 5             int rest = x % 10;
 6             m += rest * ten;
 7             x /= 10;
 8             ten /= 10;
 9         }
10         return m;
11 }

 

整体代码:

 1 class Solution {
 2 public:
 3     int reverse(int x) {
 4        unsigned int y = x;
 5         if(x<0) y=-x;
 6        if(y>INT_MAX) return 0;
 7        int reversemin(int x, int i, int ten);
 8        int reversemax(int x,int i,int ten);
 9        int m=x,i=1,ten=1;
10         while(m/=10){ ++i;ten*=10;}
11         if(i<10) m=reversemin(x,i,ten);
12         else m=reversemax(x,i,ten);
13         return m;
14     }
15 };
16 int reversemin(int x, int i, int ten)
17     {
18         int m = 0;
19         while (i--) {
20             int rest = x % 10;
21             m += rest * ten;
22             x /= 10;
23             ten /= 10;
24         }
25         return m;
26 }
27 int reversemax(int x,int i,int ten)
28 {
29     int sign=1;
30     if(x<0) {x=-x; sign=-1;}
31     int m=0,max=INT_MAX;
32     while (i--) {
33             int rest = x % 10;
34             int mrest=max/ten;
35             if(rest>mrest) return 0;
36             else if(rest<mrest) break;
37             m += rest * ten;
38             x /= 10;
39             max=max-mrest*ten;
40             ten /= 10;
41         }
42     if(ten==0) return m*sign;
43     ++i;
44     
45     while (i--) {
46             int rest = x % 10;
47             m += rest * ten;
48             x /= 10;
49             ten /= 10;
50         }
51     return m*sign;
52     
53 }

 @jm_epiphany


 

2019-03-23 新更新内容:之前一直没有看别人的解法,发现这样太过繁琐了,java中int是用补码表示的,当这个数超出范围时,他肯定和之前的码不一样了,判断不一样即可

 1 public int reverse(int x)
 2 {
 3     int result = 0;
 4 
 5     while (x != 0)
 6     {
 7         int tail = x % 10;
 8         int newResult = result * 10 + tail;
 9         if ((newResult - tail) / 10 != result)
10         { return 0; }
11         result = newResult;
12         x = x / 10;
13     }
14 
15     return result;
16 }

 

posted @ 2018-09-04 20:27  jm_epiphany  阅读(762)  评论(0编辑  收藏  举报