Encipher
Encipher

Reputation: 2866

Reverse a number using String builder in java

Problem Statement: Given a 32-bit signed integer, reverse digits of an integer.

Example 1:

Input: 123 Output: 321 Example 2:

Input: -123 Output: -321

My Solution:

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;

}

}

My Solution is ok for most of the test case. But it cannot pass one test case and I got a error

Error: Line 10: java.lang.NumberFormatException: For input string: "8463847412-"

If someone know what type of error it is please discuss.

Thank you in advance.

Upvotes: 1

Views: 1795

Answers (5)

mmirwaldt
mmirwaldt

Reputation: 883

What about this?

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;
    }
}

Output:

654321
0
-456789

This solution avoids strings and can handle negative numbers. It throws an Arithmetic exception if an integer overflow happens.

Upvotes: 0

dhanushkac
dhanushkac

Reputation: 550

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;
    }
  }
}

This code provides the output you have mentioned in the requirement. And It also supports for integer overflow. Your requirement is to convert int values. It is okay to get the converted value in the higher format since converted value may not be in the range of int. I have changed the reverse method return type to long.

I have identified a few issues in your code.

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

Above code segment, not point of checking whether the value is inside the int range because it is already received in the param as a string. It should throw an error before executing your code lines since it is not able to fit the larger value to int variable.

Finally, the int number you have used is not in the int range. (-8463847412)

Upvotes: 0

Sergei Sirik
Sergei Sirik

Reputation: 1289

If you necessarily want to implement it using StringBuilder, here it is:

  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());
  }

Output:

-321
321
0

P.S. If you want to avoid integer overflow, then you can simply use long instead of int, like this:

  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());
  }

Upvotes: 0

Karol Dowbecki
Karol Dowbecki

Reputation: 44952

By converting number to String and reversing the sign symbol ended up on the end of the value. This makes the number invalid.

You don't have to convert to String or double. You can use module operator % to extract digits:

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;
}

Upvotes: 1

Justin
Justin

Reputation: 1356

It seems like you are trying to pass in Integer.MIN_VALUE

When you pass in the minimum integer value, Math.abs seems to return a negative number as stated here

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.

You can either check for x<=Integer.MIN_VALUE and return 0 if x is Integer.MIN_VALUE or handle the special case for Integer.MIN_VALUE

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

Upvotes: 1

Related Questions