【问题标题】:Reverse a number using String builder in java在java中使用String builder反转数字
【发布时间】:2019-01-08 22:58:21
【问题描述】:

问题陈述:给定一个 32 位有符号整数,反转整数的数字。

示例 1:

输入:123 输出:321 示例 2:

输入:-123 输出:-321

我的解决方案:

class Solution7{
public int reverse(int x) {
    if(x>Integer.MAX_VALUE || x<Integer.MIN_VALUE) {
        return 0;
    }


    StringBuilder S_rev = new StringBuilder();
    String S_r_v=S_rev.append(Math.abs(x)).reverse().toString();//.toString() String builder to String

   double reverse_no=Double.parseDouble(S_r_v);

    if (x < 0) {
        return -(int)reverse_no;
    }
    return (int)reverse_no;

}

}

我的解决方案适用于大多数测试用例。但它不能通过一个测试用例,我得到一个错误

Error第 10 行:java.lang.NumberFormatException:对于输入字符串:“8463847412-”

如果有人知道这是什么类型的错误,请讨论。

提前谢谢你。

【问题讨论】:

  • 对您有帮助的两个问题:异常消息是否表明输入字符串是数字?测试用例测试与其他测试用例有何不同?
  • 您需要从反转的字符串中删除 - 。另一种解决方案是您自己在字符串生成器中进行字符反转,方法是交换所有数字但保留任何 - 原位。然后只需将结果解析回来,它将保留任何符号
  • 检查if(x&gt;Integer.MAX_VALUE || x&lt;Integer.MIN_VALUE) 没有意义。根据定义,这是不可能的。
  • 你不能反转任何 int 并且必须得到一个有效的 int。有些会超出范围。
  • 这是 Math.abs 如何处理 Integer.MIN_VALUE 的问题。看我的回答。

标签: java string stringbuilder


【解决方案1】:

您似乎正在尝试传入 Integer.MIN_VALUE

当您传入最小整数值时,Math.abs 似乎返回一个负数,如此处所述

https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#abs-int-

 Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.

您可以检查 x&lt;=Integer.MIN_VALUE 并在 x 为 Integer.MIN_VALUE 时返回 0 或处理 Integer.MIN_VALUE 的特殊情况

 if(x== Integer.MIN_VALUE)
      return -8463847412;

【讨论】:

  • 在我的代码块if(x&gt;=Integer.MAX_VALUE || x&lt;=Integer.MIN_VALUE) { return 0; } 我认为这部分处理溢出。但是我得到了这个错误:Input: 1534236469 Output: 2147483647 Expected: 0 所以我的输出与预期的输出不匹配。
  • 当你反转1534236469时,它大于Integer.MAX_VALUE(2147483647),所以看起来你需要在返回之前做一个类似于if(x&gt;=Integer.MAX_VALUE || x&lt;=Integer.MIN_VALUE)的检查。
【解决方案2】:

通过将数字转换为String 并将符号符号反转到值的末尾。这会使号码无效。

您不必转换为Stringdouble。您可以使用模块运算符% 提取数字:

public int reverse(int x) {
  long result = 0;
  while (x != 0) {
    result *= 10;
    result += x % 10;
    x /= 10;
  }
  if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
    throw new IllegalArgumentException(); // overflow
  }
  return result;
}

【讨论】:

    【解决方案3】:

    如果你一定要使用StringBuilder 来实现它,这里是:

      public static void main(String[] args) {
        ReverseNum reverseNum = new ReverseNum();
        System.out.println(reverseNum.reverse(-123));
        System.out.println(reverseNum.reverse(123));
        System.out.println(reverseNum.reverse(0));
      }
    
      public int reverse(int x) {
        int res = 1;
        String xStr = String.valueOf(x);
        StringBuilder builder = null;
    
        if (xStr.startsWith("-")) {
          builder = new StringBuilder(xStr.substring(1));
          res = -1;
        } else {
          builder = new StringBuilder(xStr);
        }
    
        return res * Integer.valueOf(builder.reverse().toString());
      }
    

    输出:

    -321
    321
    0
    

    附:如果你想避免整数溢出,那么你可以简单地使用long而不是int,像这样:

      public long reverse(int x) {
        long res = 1;
        String xStr = String.valueOf(x);
        StringBuilder builder = null;
    
        if (xStr.startsWith("-")) {
          builder = new StringBuilder(xStr.substring(1));
          res = -1;
        } else {
          builder = new StringBuilder(xStr);
        }
    
        return res * Long.valueOf(builder.reverse().toString());
      }
    

    【讨论】:

    • 不是整数溢出,是 Math.abs 处理 Integer.MIN_VALUE 的方式
    • 在我的代码中,我不使用 Math abs。来自错误消息“错误:第 10 行:java.lang.NumberFormatException:对于输入字符串:“8463847412-””数字末尾的第一个“-”。第二个即使没有“-”,“8463847412”也大于 Integer.MAX_VALUE。
    • 导致错误的输入是 -2147483648 或 Integer.MIN_VALUE。当您将 Integer.MIN_VALUE 传递给 Math.abs() 时,它会返回一个负值,这就是导致问题的原因。有关详细信息,请参阅我的答案。
    【解决方案4】:
    public class ReverseString {
      public static void main(String args[]) {
        ReverseString rs = new ReverseString();
        System.out.println(rs.reverse(-84638));
        System.out.println(rs.reverse(5464867));
      }
    
      public long reverse(int number) {
    
        boolean isNegative = number < 0;
    
        StringBuilder reverseBuilder = new StringBuilder();
        String reversedString = reverseBuilder.append(Math.abs(number)).reverse().toString();
        long reversedStringValue = Long.parseLong(reversedString);
    
        if(isNegative) {
          return reversedStringValue * -1;
        } else {
          return reversedStringValue;
        }
      }
    }
    

    此代码提供了您在要求中提到的输出。它还支持整数溢出。您的要求是转换 int 值。可以得到更高格式的转换值,因为转换后的值可能不在 int 的范围内。我已将反向方法返回类型更改为 long。

    我在您的代码中发现了一些问题。

    public int reverse(int x) {
    if(x>Integer.MAX_VALUE || x<Integer.MIN_VALUE) {
        return 0;
    }
    

    在代码段上方,不是检查值是否在 int 范围内,因为它已经作为字符串在参数中接收。它应该在执行代码行之前抛出错误,因为它无法将较大的值适合 int 变量。

    最后,你使用的 int 数不在 int 范围内。 (-8463847412)

    【讨论】:

    • 他使用的 int 数是 -2147483648 或 Integer.MIN_VALUE。当您将 Integer.MIN_VALUE 传递给 Math.abs() 时,它会返回一个负值,这就是导致问题的原因。详情请参阅我的回答。
    【解决方案5】:

    这个呢?

    public class ReverseNumber {
        public static void main(String[] args) {
            System.out.println(reverse(123456));
            System.out.println(reverse(0));
            System.out.println(reverse(-987654));
        }
    
        private static int reverse(int i) {
            final int signum;
            if(i < 0) {
                signum = -1;
            } else {
                signum = +1;
            }
    
            int reversedNumber = 0;
            int current = Math.abs(i);
    
            while(0 < current) {
                final int cipher = current % 10;
    
                reversedNumber = Math.addExact(Math.multiplyExact(reversedNumber, 10), cipher);
                current = current / 10;
            }
    
            return signum * reversedNumber;
        }
    }
    

    输出:

    654321
    0
    -456789
    

    此解决方案避免使用字符串并且可以处理负数。 如果发生整数溢出,它会抛出算术异常。

    【讨论】:

      猜你喜欢
      • 2022-11-19
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 2012-04-01
      • 2021-12-03
      相关资源
      最近更新 更多