zoukankan      html  css  js  c++  java
  • [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 }
    原创供学习参考使用,转载请注明出处http://www.cnblogs.com/cuphoria/ @jm_epiphany
  • 相关阅读:
    nginx location 语法
    nginx 日志文件
    nginx 配置文件详解
    mysql分区partition
    MySQL跳过密码登录
    min/max优化,count ,group by
    in型子查询陷阱,exists子查询
    explain分析sql效果
    HDU2896 病毒侵袭 —— AC自动机
    二分图之 多重匹配 和 最大权匹配 等总结
  • 原文地址:https://www.cnblogs.com/cuphoria/p/9588283.html
Copyright © 2011-2022 走看看