【问题标题】:Problem with Reversing Large Integers On Leetcode?在 Leetcode 上反转大整数的问题?
【发布时间】:2021-02-26 12:32:11
【问题描述】:

我正在解决 Leetcode 的这个问题,它要求反转数字,同时保持在 +/-2^31 范围内。我检查了针对这个问题的其他解决方案,并从那里创建了我自己的解决方案。它成功地适用于从 10 到小于 99,999,999 的数字。超出此范围(尝试提交代码以转到下一个问题时)会引发错误:

“第 17 行:字符 23:运行时错误:有符号整数溢出:445600005 * 10 无法在类型 'int' (solution.cpp) 中表示”

这是尝试提交代码时给出的输入:1534236469

我的代码

class Solution {
public:
    int reverse(int x) {
      int flag = 0;
      int rev = 0;
      if (x >= pow(2, 31)) {
          return 0;
      } else {
        if (x < 0) {
            flag = 1;
            x = abs(x);
        }
        while(x > 0) {
            rev = rev * 10 + x % 10;
            x /= 10;
        }
        if (flag == 1) {
            rev = rev*(-1);
        }
        
    return rev;    
    }  
    }
};

从我的代码中可以看出,我添加了一个 if 语句,如果数字大于 2^31,则基本上返回 0。不幸的是,这是错误的。

谁能解释一下如何解决这个问题?提前谢谢你。

【问题讨论】:

  • 如果您将整数保存为字符串(十进制),则反转整数非常容易。
  • 任何只使用整数值的pow,尤其是2 的整数幂,都是自动错误的。这不是pow 的用途,这类问题只是基础数学的练习题。不幸的是,像“Leetcode”这样的网站不是 C++ 教程网站,在教授 C++ 基础知识方面几乎没有价值。这不是这些网站的用途。它们只是随机编码难题的列表,要真正学习如何在 C++ 中完成这些事情,需要a good C++ textbook
  • 反转 1534236469 会使您超出该范围。你应该检查你的结果,而不是输入。 (并且限制是整数1 &lt;&lt; 31,而不是浮点数pow(2,31)。)
  • 我不明白我到处都知道使用 pow 可以将数字的幂提高到你想要的程度??
  • @Thanos 因为它们都转换为浮点数en.cppreference.com/w/cpp/numeric/math/pow 现在你在那个美妙的地方,如果一个特定的浮点表示可以精确地保持整数值,你必须锻炼。最好不要问这个问题。

标签: c++ integer overflow


【解决方案1】:

如果倒数不属于整数范围,问题语句要求返回0:

如果反转x 导致值超出有符号的32 位整数范围[-2^31, 2^31 - 1],则return 0

在您的代码中,您检查了输入是否在整数范围内,但是当整数有 10 位且最后一位为 >2(在某些情况下为 2)时,它们会出现极端情况。

让我们考虑输入1534236469: 1534236469

所以程序按预期执行现在让我们跟踪程序执行的最后几个步骤: rev = 964632435x = 1 执行以下语句时会出现问题:

rev = rev * 10 + x % 10;

现在,即使输入可以表示为整数rev * 10 ,即9646324350 大于整数范围,并且应该返回的正确值是

修复?

1。让我们独立考虑 10 位大小写

虽然可以这样做,但当最后一位为 2

时会引起不必要的麻烦

2。使rev 成为long integer

这很好用,也被接受了,但遗憾的是,在解决这个问题时这不是预期的,因为声明明确要求不要使用 64 位整数

假设环境不允许您存储 64 位整数(有符号或无符号)。

3。在乘以 10 之前检查?

这按预期工作。在将rev 乘以10 之前检查它是否是&gt;= (pow(2,31)/10)

while(x > 0) {
            if (rev >= pow(2, 31)/10 )
                return 0;
            rev = rev * 10 + x % 10;  
            x /= 10;
        }

我希望这能解决您的疑问!如果您发现有问题,请发表评论,因为这是我的第一个答案。

注意:以下if 语句是不必要的,因为输入始终是一个 32 位整数

给定一个有符号32位整数x

if (x >= pow(2, 31)) {
          return 0;
      } 

编辑:正如大多数 cmets 指出的那样,使用 INT_MAX 宏就足够了,而不是 pow(2,31)

【讨论】:

  • 感谢您的回复,它确实帮助我更好地理解了这一点。但是,对于整个 INT_MAX 而言,您将如何使用它来代替 pow?
  • Numeric Limits 页面描述了这些限制的使用。你可以参考这个,或者快速谷歌搜索会导致更多可读的帖子。
  • 好的,非常感谢您的帮助
【解决方案2】:
 public static int reverse(int x) {
        boolean isNegative = false;
        if (x < 0) {
            isNegative = true;
            x = -x;
        }
        long reverse = 0;
        while (x > 0) {
            reverse = reverse * 10 + x % 10;
            x=x/10;
        }
        if (reverse > Integer.MAX_VALUE) {
            return 0;
        }
        return (int) (isNegative ? -reverse : reverse);
    }

【讨论】:

  • 这个问题被标记为 C++ 但那不是 C++
猜你喜欢
  • 1970-01-01
  • 2020-01-14
  • 2022-07-08
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 2022-11-03
  • 2022-06-12
  • 1970-01-01
相关资源
最近更新 更多