【问题标题】:Reverse of a number taking care of boundary conditions考虑边界条件的数字的反转
【发布时间】:2014-10-06 18:00:43
【问题描述】:

我正在尝试用 Java 编写一个简单的方法,该方法返回一个数字的倒数(以数学方式,而不是字符串方式)。我想处理边界条件,因为反向超出 int 范围的数字会给我一个错误的答案。即使抛出异常,我也没有得到明确的逻辑。我试过这个代码。

private static int reverseNumber(int number) {
int remainder = 0, sum = 0; // One could use comma separated declaration for primitives and
                            // immutable objects, but not for Classes or mutable objects because
                            // then, they will allrefer to the same element.
boolean isNegative = number < 0 ? true : false;
if (isNegative)
  number = Math.abs(number); // doesn't work for Int.MIN_VALUE
                             // http://stackoverflow.com/questions/5444611/math-abs-returns-wrong-value-for-integer-min-value

System.out.println(number);
while (number > 0) {
  remainder = number % 10;
  sum = sum * 10 + remainder;
  /* Never works, because int won't throw error for outside int limit, it just wraps around */
  if (sum > Integer.MAX_VALUE || sum < Integer.MIN_VALUE) {
    throw new RuntimeException("Over or under the limit");
  }
  /* end */
  /* This doesn't work always either.
   * For eg. let's take a hypothetical 5 bit machine.
   * If we want to reverse 19, 91 will be the sum and it is (in a 5 bit machine), 27, valid again!
   */
  if (sum < 0) {
    throw new RuntimeException("Over or under the limit");
  }

  number /= 10;
}
return isNegative ? -sum : sum;

}

【问题讨论】:

  • 您可以使用longs,并根据需要比较它们以适应int的范围。
  • 请提供一些输入示例和您的预期输出。 in the mathematical way, not string-wise - 似乎有点模棱两可。
  • @dognose 我的意思是我不想将其转换为字符串然后反转它。
  • @Srivatskrishnan 好的,所以“9876”仍应变为“6789” - 但使用“计算”​​,而不是字符串操作?
  • @dognose 没错。

标签: java integer-overflow boundary


【解决方案1】:

您除以 10 的方法,将提醒转移到当前结果 * 10 是要走的路。

你做错的唯一一件事是检查“边界违规”,因为

sum > Integer.MAX_VALUE || sum < Integer.MIN_VALUE

可以。永远不要是真的 - 否则 MIN 和 MAX 将没有任何意义。

所以,想想数学 :-)

sum = sum * 10 + remainder;

不应超过Integer.MAX_VALUE,即

                 (!)
Integer.MAX_VALUE >= sum * 10 + remainder;

或转换:

                                    (!)
(Integer.MAX_VALUE - remainder) / 10 >= sum

因此,您可以在乘以 10 并添加余数之前使用以下检查:

while (number > 0) {
  remainder = number % 10;

  if (!(sum <= ((Integer.MAX_VALUE -remainder) / 10))) {
    //next *10 + remainder will exceed the boundaries of Integer.
    throw new RuntimeException("Over or under the limit");
  }

  sum = sum * 10 + remainder;
  number /= 10;
}

简化(DeMorgan)条件为

if (sum > ((Integer.MAX_VALUE -remainder) / 10))

这很有意义 - 因为它正好是你下一步将是什么的反向计算 - 如果 sum 已经大于这个计算 - 你将在下一步超过 Integer.MAX_VALUE

未经测试,但这应该可以解决它。

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2014-04-16
    • 2012-05-06
    • 2019-04-13
    相关资源
    最近更新 更多