反转 32 位整数

Reverse 32bit integer

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

任务是:

Return 有符号 32 位整数的倒数,return 0 如果它溢出 32 位有符号整数的范围。

Wikipedia中:

A 32-bit register can store 32 different values. The range of integer values that can be stored in 32 bits depends on the integer representation used. With the two most common representations, the range is 0 through 4,294,967,295 (2^32 − 1) for representation as an (unsigned) binary number, and −2,147,483,648 (−2^31) through 2,147,483,647 (2^31 − 1) for representation as two's complement.

所以,如果我的理解是正确的,我应该在区间 0 to (2^31)-1(-2^31) to 0 之间进行测试,否则 return 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 范围内吗?我缺少什么?

如评论中所述,您必须先反转,然后检查。然而,这里有一种不同的检查方式。

要检查,您可以 & 使用适当掩码的结果。

所以在你的情况下,限制是 −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 并根据解释的逻辑检查它们。

解决方案已经存在,我发布这个是因为这可能对像我这样的新手有帮助。我使用了 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

出现这种情况是因为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

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

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

简单纯数学-

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)

基于@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

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

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

我是 Python 的新手所以请批评 -- 事实上这是我的第一个 Python 函数也是第一个 'class'.

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

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、and/or 符号也很容易,但不会使它不太清楚。

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