繁体   English   中英

反转leetcode中的整数

[英]Reverse an integer in leetcode

我正在尝试解决反向整数问题,我们必须牢记要处理溢出问题。

阅读其他解决方案并进行尝试,我编写了解决方案

class Solution {
public:
  int reverse(int x) {
  int result = 0;
  int old_result = 0;
  while(x) {
    old_result = result;
    result = result*10 + x%10;
    if ((result-old_result*10)!=x%10)
        return 0;
    x = x/10;
  }
  return result;
  }
};

由于溢出处理不当,因此未接受答案。 原来是变化

if ((result-old_result*10)!=x%10)

if ((result-x%10)/10!=old_result)

会使事情工作。

我觉得这些行正在做同样的检查。 不知道为什么一个人通过而一个人失败。

谁能帮忙解释一下?

我觉得这些行正在做同样的检查。 不知道为什么一个人通过而一个人失败。

不必要。 如果old_result的值大于(或等于) std::numeric_limits<int>::max () / 10 + 1 ,则表达式old_result*10会溢出,这将给您错误的答案。

整数类型的溢出是未定义的行为。 这是C ++(C ++ 11 / C ++ 14 / C ++ 17)标准草案的精髓(我没有完整版标准的访问权限,而且在大多数情况下,这已经足够了) :

如果在表达式的求值过程中,未在数学上定义结果或该类型的结果不在可表示的值范围内,则行为不确定。

if的第二种形式(重新排序)消除了乘法-有效地增加了值的范围,可以在old_result

   result = result*10 + x%10;

   if ((result-old_result*10)!=x%10)
   // or
   if ((result-x%10)/10!=old_result)

result*10 + x%10;之后编码时,两者都是不好的result*10 + x%10; 因为可能已经发生了溢出。

对于行为良好的代码,应避免int溢出。

与其以某种方式依赖于溢出行为,不如计算result*10 + x%10是否会溢出。

  // for positive numbers
  int max = std::numeric_limits<int>::max
  while(x) {
    int digit = x%10;
    if (result >= max/10 && (result > max/10 || digit > max%10)) {
      Overflow();
    }
    result = result*10 + digit;
    x = x/10;
  }

请注意,带签名的数字溢出是 特定 实现的 UB,因此我建议改用unsigned 然后考虑它使用的属性与未签名的属性相似,并假定result = result*10 + x%10; 溢出。 然后:

result -= old_result * 10;

以相同的方式“还原”溢出。

而以下是正确的

(result - x % 10) == old_result * 10; // With possible overflow in both side.

两侧除以10只能通过简化来消除溢出

(result - x % 10) / 10 == old_result;
// overflow on left side (before division). No overflow on right side.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM