Reverse a number using String builder in java - 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.

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;

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

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

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)

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.

Related

Reverse an int using recursion

I want to reverse an int but it doesn't work. For example, 123 should return 321, but the printed number is 356.
public class x {
public static void main(String[] args) {
System.out.println(reverse2(123, 0));
}
static int reverse2(int a, int i) {
if(a == 0) {
return 0;
} else {
i = i*10 + a%10;
System.out.println(i);
return i += reverse2(a/10, i);
}
}
}
Your code should look like this:
public class x {
public static void main(String[] args) {
System.out.println(reverse2(123, 0));
}
static int reverse2(int a, int i) {
if(a == 0) {
return i;
} else {
i = i*10 + a%10;
System.out.println(i);
return reverse2(a/10, i);
}
}
}
You should return i when a is 0.
You shouldn't add i when you call the reverse2 function because you're adding i twice.
You are greatly complicating your recursive function for printing an integer in reverse. For one, there is no good reason for reverse2 to have two integer arguments, as you can achieve your desired results with a single argument. The trick is to access the rightmost digit with the % 10 operation then shift that digit off the number with the / 10 operation. Consider these revisions:
public class x {
public static void main(String[] args) {
System.out.println(reverse2(123));
}
static String reverse2(int number) {
if(number == 0) {
return "";
} else {
return number % 10 + reverse2(number / 10);
}
}
}
You can do it like this. You only need to pass the value you are reversing. The math computation computes 10 to the power of the number of digits in the argument.
public static int reverse(int v) {
int reversed = 0;
if (v > 0) {
int d = (int)Math.pow(10,(int)(Math.log10(v)));
reversed = reverse(v%d) * 10 + v/d;
}
return reversed;
}
Of course, if you can pass a second argument as a scratch pad, then it can be done like so. As you tear down the original value you build up the returned value.
public static int reverse(int v, int reversed) {
if (v > 0) {
return reverse(v / 10, reversed * 10 + v % 10);
}
return reversed;
}

Conversion of decimal into binary using recursion

I want to convert the decimal number into a binary number using recursion in java. I tried a lot but unable to do it. Here is my code:
public class DecimalToBinary {
public static void main(String[] args) {
System.out.println(conversion(2));
}
public static int conversion(int n) {
return reconversion(n);
}
public static int reconversion(int n) {
if(n <= 0)
return 0;
else {
return (int) (n/2 + conversion(n/2));
}
}
}
Integer values are already in binary. The fact that they appear as digits 0 thru 9 when you print them is because they are converted to a string of decimal digits. So you need to return a String of binary digits like so.
public static String conversion(int n) {
String b = "";
if (n > 1) {
// continue shifting until n == 1
b = conversion(n >> 1);
}
// now concatenate the return values based on the logical AND
b += (n & 1);
return b;
}

Get int array values from int bit base 2 value

I have bit representation like below
Bit 0(2^0 .= 1) - 1
Bit 1(2^1 .= 2) - 2
Bit 2(2^2 .= 4) - 4
Bit 3(2^3 .= 8) - 8
Bit 4(2^4 .= 16) - 16
A value of 7 means we have 1+2+4. But how do i get this array programmatically?
Continuosly divide by 2 and save the remainder
int n = 7;
StringBuilder sb = new StringBuilder();
while(n>0) {
sb.append(n%2);
n = n/2;
}
System.out.println(sb.reverse().toString());
You can store it anyway you want. Currently it is stored as string (Binary Representation of 7).
To convert back from the string to binary, start from LSB and add by powers of 2 of the bit position if the bit value is 1
Simple logic, works up to intmax (Very easy to change to max long by just changing type :))
public static void main(String[] args) {
int originalInt = 127;
toIntegerArray(originalInt);
}
private static List<Integer> toIntegerArray(int originalInt) {
String bits = Integer.toBinaryString(originalInt);
// Reversed, for easier logic when building string
StringBuilder s = new StringBuilder(bits).reverse();
char[] bitArray = s.toString().toCharArray();
List<Integer> result = new ArrayList<>();
for (int i = 0; i < bitArray.length; i++) {
if (bitArray[i] == '1') {
result.add((int) Math.pow(2, i));
}
}
System.out.println("Original int: " + originalInt);
System.out.println("Bit pattern: " + bits);
System.out.println(result);
return result;
}
I got below working, but for values below 31. Any suggestion on how to allow any value?
public static void Main(string[] args)
{
Console.WriteLine();
Console.WriteLine("[{0}]", string.Join(", ", log3(100)));
}
static int[] log3(int x) {
List<int> pow = new List<int>();
int val=x;
do{
if(x>= 1 << val){
if(1<<val>0){
pow.Add(1<<val);
}
x-=1<<val;
}
val-=1;
}while(val>=0);
return pow.ToArray();
}
Here is a recursive streaming option:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Class {
private static IntStream intToBinaryParts(final int input, final int count) {
int powerOf2 = (int) Math.pow(2, count);
if (count < 0) {
return IntStream.empty();
} else if (input < powerOf2) {
return intToBinaryParts(input, count - 1);
} else {
return IntStream.concat(intToBinaryParts(input - powerOf2, count - 1), IntStream.of(powerOf2));
}
}
public static List<Integer> intToBinaryParts(final int input) {
return intToBinaryParts(input, (int) Math.ceil(Math.log(input) / Math.log(2)))
.mapToObj(Integer::new)
.collect(Collectors.toList());
}
public static void main(String... args) {
System.out.println(intToBinaryParts(7));
System.out.println(intToBinaryParts(8));
System.out.println(intToBinaryParts(100));
System.out.println(intToBinaryParts(1234567890));
}
}

how to use recursion for converting String to int

I want to convert String input into int using recursion. This is the code I came up with but if my input is 123456 it only returns 124. If I enter 1234567, it gives an error.
import java.util.*;
public class Problem1 {
static int x =0;
static int counter = 0;
//input
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String s= scan.nextLine();
System.out.println(recursive(s));
}
//recursive method
public static int recursive(String s){
if(s.length()==1){
x=(x*10)+ Integer.parseInt(s.substring(0,1));
return x;
}
else{
x = (x*10)+Integer.parseInt(s.substring(0,1));
counter++;
return recursive(s.substring(counter,s.length()-1));
}
}
}
import java.util.Scanner;
public class Problem1 {
static int x = 0;
static int counter = 0;
// input
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
System.out.println(recursive(s));
}
// recursive method
public static int recursive(String s) {
if (s.length() == 1) {
x = (x * 10) + Integer.parseInt(s.substring(0, 1));
return x;
} else {
x = (x * 10) + Integer.parseInt(s.substring(0, 1));
counter++;
return recursive(s.substring(1, s.length()));
}
}
}
Look at your static counter variable. You are incrementing it every time. But you only want to have the substring starting at 1 (so cut off the first "letter").
So instead of using:
counter++;
return recursive(s.substring(counter,s.length()-1));
consider using:
return recursive(s.substring(1)); // you even don't really need the length
Because the String s parameter is as follows:
1st call: 1234567
2nd call: 234567
3rd call: 34567
4th call: 4567
...
So, you only have to cut off the first letter.
Btw: your sample "project" is a really funny one ;)
A few notes to start:
If you're doing recursion, you probably don't want to use a member variable. It's not wrong to do so, but not really typical of the pattern (your x variable).
It's often handy to pass in state through the recursion, although you wouldn't have to (that is, current value of x).
Your case is a little odd because you have to change your current parse value for every sub-parse (shifting by 10 each time); makes it a little more complicated.
If you are going to keep x as a member variable (which does seem to make sense in this case), you don't need to return anything from recursive.
Can you really not just use Integer.parseInt()?
Code could be much more simple, something like:
void recursive (String s)
{
if (s.length() == 0) return 0;
x = x * 10 + Integer.parseInt(s.substring(0, 1));
recursive(s.substring(1));
}
recursion("1234567", 0, 1)
The above code will turn the string "1234567" into an int using recursion. You must pass the string you want to convert, and then 0 and 1.
public static int recursion(String s, int result, int place) {
result += place * Integer.parseInt(s.charAt(s.length() - 1) + "");
if(s.length() == 1) {
return result;
}
else {
return recursion(s.substring(0, s.length() - 1), result, place * 10);
}
}
public static int computeStr(String str) {
if (str.equals("")) {
return 0;
}
int x = 1;
for (int i = 0; i < str.length() - 1; i++) {
x = x * 10;
}
x = x * Integer.parseInt(str.substring(0, 1));
return x + computeStr(str.substring(1));
}
For example: "2432" is (2 * 1000) + (4 * 100) + (3*10) + (2*1) = 2432
this algorithm begins at first position (2) from 2432
I know its kind of a late response but you could try something like this :-
private static int stringToInt(String string) {
if (string.length() == 0) {
return 0;
}
int rv;
int num = string.charAt(string.length() - 1) - '0';
String restOfTheString = string.substring(0, string.length() - 1);
rv = stringToInt(restOfTheString) * 10 + num;
return rv;
}
Try something like this:
Subtracting the ASCII code of the '0' character from your character returns an integer:
public class StringRecursion {
static int counter = 0;
public static void main(String[] args) {
System.out.println(convertStringToInt("123456"));
}
public static int convertStringToInt(String input) {
if (input.length() == 1)
return input.charAt(0) - '0';
int value = convertStringToInt(input.substring(0, input.length() - 1));
counter++;
return value * 10 + input.charAt(counter) - '0';
}
}
Try it like this :
public static int conStrToInt(String str) {
if(str.length()==0)
{
return 0;
}
char cc = str.charAt(0);
String ros = str.substring(1);
int factor=1;
for(int i=0;i<str.length()-1;i++)
factor*=10;
factor=factor*(cc-'0');
return factor+conStrToInt(ros);
}

How to get the length of a numbers fraction part?

How do I find out the length or the number of digits of the fraction part of a decimal number?
I can see a few aproaches, e.g. with Strings like this one:
public static int getNumberOfFractionDigits(Number number) {
Double fractionPart = number.doubleValue() - number.longValue();
return fractionPart.toString().length() - 2;
}
But what is the best way to determine the length?
I could imagine some problems if I use Strings, e.g. because the locale and number format may be different from system to system. Is there a nice way to calculate it? Maybe without iteration?
Thanks in advance.
Try this:
public static int getNumberOfFractionDigits(Number number) {
if( number == null ) return 0; //or throw
if( number.doubleValue() == 0.0d ) return 0;
BigDecimal bd = new BigDecimal(number.toString());
//BigDecimal bd = BigDecimal.valueOf(number.doubleValue()); // if double precision is ok, just note that you should use BigDecimal.valueOf(double) rather than new BigDecimal(double) due to precision bugs in the latter
bd = bd.stripTrailingZeros(); //convert 1.00 to 1 -> scale will now be 0, except for 0.0 where this doesn't work
return bd.scale();
}
Edit:
If the number is actually an iteger (i.e. fraction of 0) this would still return 1. Thus you might check whether there actually is a fractional part first.
Edit2:
stripTrailingZeros() seems to do the trick, except for 0.0d. Updated the code accordingly.
I just wrote a simple method for this, hope it can help someone.
public static int getFractionDigitsCount(double d) {
if (d >= 1) { //we only need the fraction digits
d = d - (long) d;
}
if (d == 0) { //nothing to count
return 0;
}
d *= 10; //shifts 1 digit to left
int count = 1;
while (d - (long) d != 0) { //keeps shifting until there are no more fractions
d *= 10;
count++;
}
return count;
}
You may use java.text.NumberFormat.
nf = java.text.NumberFormat.getInstance ();
// without BigDecimal, you will reach the limit far before 100
nf.setMaximumFractionDigits (100);
String s = nf.format (number.doubleValue ())
You may set the Decimal-Identifier as you like, and use regular expressions to cut off the leading part, and String.length () to evaluate the rest.
Looks like many offered the Big Decimal. It's easy on the eyes at least.
The code shall work for ya.
package t1;
import java.math.*;
public class ScaleZ {
private static final int MAX_PRECISION = 10;
private static final MathContext mc = new MathContext(MAX_PRECISION, RoundingMode.HALF_EVEN);
public static int getScale(double v){
if (v!=v || v == Double.POSITIVE_INFINITY || v == Double.NEGATIVE_INFINITY)
return 0;//throw exception or return any other stuff
BigDecimal d = new BigDecimal(v, mc);
return Math.max(0, d.stripTrailingZeros().scale());
}
public static void main(String[] args) {
test(0.0);
test(1000d);
test(1d/3);
test(Math.PI);
test(1.244e7);
test(1e11);
}
private static void test(double d) {
System.out.printf("%20s digits %d%n", d, getScale(d));
}
}
That was my best implementation:
public class NumberHandler {
private static NumberFormat formatter = NumberFormat.getInstance(Locale.ENGLISH);
static {
formatter.setMaximumFractionDigits(Integer.MAX_VALUE);
formatter.setGroupingUsed(false);
}
public static int getFractionLength(double doubleNumber) {
String numberStr = formatter.format(doubleNumber);
int dotIndex = numberStr.indexOf(".");
if (dotIndex < 0) {
return 0;
} else {
return numberStr.length() - (dotIndex + 1);
}
}
}
Not effective, probably not perfect, but the other options was worse.
public static int getNumberOfFractionDigits(double d) {
String s = Double.toString(d), afterDecimal="";
afterDecimal = s.subString(s.indexOf(".") + 1, s.length() - 1);
return afterDecimal.length();
}

Categories