[英]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.