【问题标题】:Reverse 32bit integer反转 32 位整数
【发布时间】:2017-11-18 18:20:37
【问题描述】:

我正在尝试解决leetcode.com 中处理signed 32bit integers 的练习。

任务是:

返回带符号的 32 位整数的倒数,如果超出 32 位带符号整数的范围,则返回 0。

Wikipedia:

一个 32 位寄存器可以存储 32 个不同的值。整数范围 可以存储在 32 位中的值取决于整数 使用的表示。有两种最常见的表示, 范围是 0 到 4,294,967,295 (2^32 − 1) 表示为 (无符号)二进制数,-2,147,483,648 (-2^31) 到 2,147,483,647 (2^31 − 1) 表示为二进制补码。

所以,如果我的理解是正确的,我应该在间隔 0 to (2^31)-1(-2^31) to 0 之间进行测试,否则返回 0

这是我的代码:

def reverse_int(nums):
    a = str(nums)

    if 0 < nums <= (1 << 31)-1:
        return int(a[::-1])

    elif (-1 << 31) <= nums < 0:
        return -(int(a[:-len(a):-1]))
    else:
        return 0

这是我的问题: 当我在网站上测试我的代码时:

nums = 1534236469 # Fail
nums = 1463847412 # Success
nums = 9000000    # Success

为什么我当前的代码因1534236469 而失败? 1534236469 不是在 32 bit signed integers 的范围内吗?我错过了什么?

【问题讨论】:

  • 在失败的情况下你会得到什么输出?
  • 例如,对于网站上的1534236469,它应该返回0。这意味着1534236469 溢出了32 位有符号整数的范围。
  • 但不会溢出。
  • 在维基百科中他们说the two most common representations。 32位整数还有其他表示吗?
  • 你需要反转然后检查是否溢出。

标签: python integer 32-bit


【解决方案1】:

如 cmets 中所述,您必须先反转,然后再检查。但是,这里有一种不同的检查方式。

要检查你可以&amp; 带有适当掩码的结果。

所以在你的情况下,限制是 −2,147,483,6482,147,483,647 它们的十六进制值是 -0x800000000x7fffffff

在解释器中试试这个。

>>> 0x7fffffff
2147483647
>>> 2147483647 & 0x7fffffff   #within limit
2147483647

超过限制的值,你可以看到显示了一些其他值。

>>> 2147483648 & 0x7fffffff     #Exceeds limit
0
>>> 98989898989898 & 0x7fffffff  #Exceeds limit
1640235338

但是当值在限制范围内时。该值作为输出给出。

>>> 1 & 0x7fffffff               #within limit
1
>>> 780 & 0x7fffffff
780

对于负值

 >>> -0x80000000     #Limit
-2147483648
>>> -2147483648 & -0x80000000
-2147483648

当值在范围内时。 限制作为输出给出。

>>> -2147483647 & -0x80000000
-2147483648
>>> -2 & -0x80000000          #within limit
-2147483648
>>> -2323 & -0x80000000
-2147483648

但是,如果值超出范围,您可以看到显示其他值。

>>> -2147483649 & -0x80000000
-4294967296
>>> -999999999999 & -0x80000000
-1000727379968

你可以好好利用这个,得到你想要的!

这是一个可以满足您的需求的程序。

def reverse(x):
    str_x = str(x)
    if x<0:
        str_x = '-'+str_x[::-1][:-1]
        x = int(str_x)
    else:
        str_x = str_x[::-1]
        x = int(str_x)
    neg_limit= -0x80000000
    pos_limit= 0x7fffffff

    if(x<0):
        val=x&neg_limit
        if(val==neg_limit):
            return x
        else:
            return 0
    elif(x==0):
        return x
    else:
        val = x&pos_limit
        if(val==x):
            return x
        else:
            return 0

value = int(input("Enter value: "))
print(reverse(value))

下面的部分对于负值和正值都是相反的。

if x<0:
    str_x = '-'+str_x[::-1][:-1]
    x = int(str_x)
    print(x)
else:
    str_x = str_x[::-1]
    x = int(str_x)
    print(x)

设置限制neg_limit= -0x80000000pos_limit= 0x7fffffff并根据解释的逻辑检查它们。

【讨论】:

  • 或者,如果它在(-1 &lt;&lt; 31)(1 &lt;&lt; 31)-1 之间,则以更简单的方式比较str_x 的反向int。如果没有返回0。顺便说一句,你的方法也是正确的,但是太冗长了。
  • 是的,但想提一下&amp;的使用和mask的使用
【解决方案2】:

解决方案已经存在,我发布这个是因为这可能对像我这样的新手有帮助。我使用了 void 的 解决方案(上图)来完成它。起初,我在没有执行反向方法的情况下进行了测试,它显示了原始问题中提到的问题。然后我在颠倒正负情况下的数字后进行了测试,结果成功了。

def reverse(self, x: int) -> int:
        neg_limit =-0x80000000 # hex(-2**31-1),see details in accepted answer above
        pos_limit = 0x7fffffff #hex(2**31-1)
        if x >0:
            reverse_num = int(str(x)[::-1])
            if reverse_num & pos_limit==reverse_num: #conditions explained above
                return reverse_num
            else:
                return 0

        elif x <0:
            reverse_num = -int(str(abs(x))[::-1])
            if reverse_num&neg_limit == neg_limit:
                return reverse_num
            else:
                    return 0
        else:
            return 0

【讨论】:

    【解决方案3】:

    出现这种情况是因为 nums = 1534236469 在 32 位有符号整数范围内,但反过来 9646324351 不在 32 位有符号整数范围内。

    class Solution:
    def reverse(self, x: int) -> int:
        if x in range((-1 << 31),(1 << 31)-1):
            r=0
            c=False
            if(x<0):
                c=True
                x*=-1
    
            while(x!=0):
                r=10*r+x%10
                x=x//10
            if(c):
                r*=-1
            if r in range((-1 << 31),(1 << 31)-1):
                return r
            else:
                return 0
        else:
            return 0
    

    【讨论】:

      【解决方案4】:

      简单而纯粹的数学 -

      def reverse(self, x: int) -> int:
              r = 2 ** 31
              maxLimit = r - 1
              minLimit = r * -1
              rev = None
              negative = False
      
              if x < 0:
                  negative = True
                  x = x * -1
      
              while True:
                  mod = x % 10
                  x = (x - mod) / 10
      
                  if not rev:
                      rev = mod
                  else:
                      rev = (rev * 10) + mod
      
                  if x <= 0:
                      break
      
              if negative:
                  rev = rev * -1
      
              returnValue = int(rev)
              if returnValue < minLimit or returnValue > maxLimit:
                  return 0 #Return whatever you want. if overflows
              return int(rev)
      

      【讨论】:

      • 很好的数学思维方式。我以更 Pythonic 的方式重写了它。语句rev * 10 + mod 会导致溢出。
      【解决方案5】:

      基于@Keshari 解决方案的简单、数学和pythonic 方式

      def reverse(x):
          is_neg = x < 0
          imax = (1 << 31) - 1
          imin = (-1 << 31)
          r = 0
          x = abs(x)
          while x:
              x, m = divmod(x, 10)
              if (r > imax / 10) or (r == imax / 10 and m > 7):
                  return 0
              if (r < imin / 10) or (r == imin / 10 and m < -8):
                  return 0
              r = (r * 10) + m
          return r * -1 if is_neg else r
      

      【讨论】:

        【解决方案6】:

        另一种不使用任何附加变量限制结果溢出的方法是:

        def reverse(x):
            num = str(abs(x))
        
            if x < 0:
                result = -1 * int(num[::-1])
            else:
                result = int(num[::-1])
        
            if result not in range((-1 << 31), (1 << 31) - 1):
                return 0
        
            return result
        

        【讨论】:

          【解决方案7】:

          反转有符号整数,但如果超出 int32 限制,则返回 0,如低于 2^31 或高于 2^31 -1。

          [将其嵌入解决方案类是问题站点要求的一部分。]

          我是 Python 新手,所以请批评——事实上,这是我的第一个 Python 函数和第一个“类”。

          执行以下操作似乎简单明了:

          class Solution:
              def reverse(self, x: int) -> int:
                  s = str(abs(x))[::-1]
                  sign = -1 if x < 0 else 1
                  rx = int(s) * sign
                  return 0 if rx < -2**31 or rx > 2**31 - 1 else rx
          

          折叠临时值 s、rx 和/或符号也很容易,但不这样做就不太清楚了。

          说真的,我很感激批评,因为这实际上是我的第一个 Python;多年来一直想学习它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-09-18
            • 1970-01-01
            • 2019-08-17
            • 1970-01-01
            • 2011-06-10
            • 2011-06-15
            • 2011-10-25
            相关资源
            最近更新 更多