我试图解决反向整数问题,我们必须记住处理溢出问题。
阅读其他解决方案并试用,我写了我的解决方案
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)
会让事情奏效。
我觉得这些线都在做同样的检查。不知道为什么一个人通过,一个人失败。
任何人都可以帮忙解释一下吗?
答案 0 :(得分:1)
我觉得这些线都在做同样的检查。不确定为什么一个人通过,一个人失败。
不一定。如果old_result
的值超过(或等于)std::numeric_limits<int>::max () / 10 + 1
,则表达式old_result*10
会溢出,这会给您错误的答案。
整数类型的溢出是未定义的行为。这是完全来自C ++(C ++ 11 / C ++ 14 / C ++ 17)标准草案(我无法访问完整版标准,并且在大多数情况下,它已经足够了) :
如果在评估表达式期间,结果未在数学上定义或不在范围内 其类型的可表示值,行为未定义。
if
的第二种形式(重新排序)删除了乘法 - 有效地增加了可以在old_result
中使用的值范围。
答案 1 :(得分:1)
result = result*10 + x%10;
if ((result-old_result*10)!=x%10)
// or
if ((result-x%10)/10!=old_result)
在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;
}
答案 2 :(得分:0)
请注意,带有签名号码的溢出是特定于实现的 UB,因此我建议使用unsigned
代替。然后考虑它使用类似的属性而不是unsigned,并假设result = result*10 + x%10;
溢出。然后:
result -= old_result * 10;
&#34;回复&#34;以同样的方式溢出。
而以下是真的
(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.