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);
}
Related
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;
}
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.
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));
}
}
I am trying to convert an integer to a binary number string, and I wrote the code for it and it compiled. However, I can't seem to write a test file for it, i keep getting an error. I am supposed to write a separate test file that outputs my answer, however I am not sure how to do that. I'm pretty new to Java. Can anyone help me figure out how to fix the error I get?
This is my java code for to convert it.
public String binaryNumber( int j)
{
String n = "";
String a = "";
do
{
a += (j % 2);
j = j/2;
}while (j != 0);
for(int r = (a.length() - 1); r >=0; r--)
{
n += a.charAt(r);
}
return n;
}
public String getN {return n;}
This is my test code :
public class BinaryNumberTest
{
public static void main(String[] args)
{
System.out.println("Result: " + binaryNumber(45));
}
}
Your code seems correct if you make the binaryNumber(int j) method static. Because you can't access non-static method inside static context.
However you can use Integer.toBinaryString(x) to perform the task easily. Additionally, you can use Integer.toString(x,8) to convert octal, Integer.toString(x,2) to convert binary, Integer.toString(x,16) to convert hexa-decimal, and Integer.toString(x,n) to n base.
You should make your binaryNumber method static because you are not using instance fields.
public class BinaryNumber
{
public static String binaryNumber( int j)
{
String n = "";
String a = "";
do
{
a += (j % 2);
j = j/2;
}while (j != 0);
for(int r = (a.length() - 1); r >=0; r--)
{
n += a.charAt(r);
}
return n;
}
}
To test:
public class BinaryNumberTest
{
public static void main(String[] args)
{
System.out.println("Result: " + BinaryNumber.binaryNumber(45));
}
}
First, since binaryNumber doesn't use any instance members it could (read: should) be defined as static. Second, you need to reference it by its class name, or statically import it:
System.out.println("Result: " + BinaryNumber.binaryNumber(45));
I'm having an extremely difficult time getting a private method with arguments to be usable in my toString method but have no idea how to get the two methods to cooperate.
main class:
import static java.lang.System.*;
public class Triples
{
private int number;
public Triples()
{
//this(0);
}
public Triples(int num)
{
number = num;
}
public void setNum(int num)
{
number = num;
}
private int greatestCommonFactor(int a, int b, int c)
{
int max = number;
for(int n = 1; n <= max; n++)
{
for(a = n; a <= max; a++)
{
a = n;
for(b = a +1; b <= max; b++)
{
b =n;
for(c = b + 1; c <= max; c++)
{
c = n;
if(Math.pow(a, 2)+ Math.pow(b, 2)== Math.pow(c, 2))
{
if((a%2==1 && b%2==0)|| (a%2==0 && b%2==1))
{
if(a%2<=1 && b%2<=1 && c%2<=1)
{
String last = a + "" + b + c;
}
}
}
}
}
}
}
return 1;
}
public String toString()
{
String output="";
output = output + this.greatestCommonFactor( ) + " \n";
return output;
}
}
and for cross-referencing my runner class:
import static java.lang.System.*;
import java.util.Scanner;
public class Lab11j
{
public static void main(String args[])
{
Scanner keyboard = new Scanner(System.in);
String choice="";
do{
out.print("Enter the max number to use : ");
int big = keyboard.nextInt();
//instantiate a TriangleThree object
Triples triple = new Triples(big);
//call the toString method to print the triangle
out.println( triple );
System.out.print("Do you want to enter more data? ");
choice=keyboard.next();
}while(choice.equals("Y")||choice.equals("y"));
}
}
if you find you need clarification of this lab, here's a Google docs of the labsheet: https://docs.google.com/open?id=0B_ifaCiEZgtcX08tbW1jNThZZmM
The variables a, b & c can be used as local variables here. This would allow you to remove them from the argument list of greatestCommonFactor:
private int greatestCommonFactor() {
int a = 0;
int b = 0;
int c = 0;
...
as they are only required within the scope of the method.
Well, yeah. You're not passing anything to greatestCommonFactor. I'm not sure what you expected to happen in your toString() method when you didn't pass enough arguments to a method.
you need to pass them like
output = output + this.greatestCommonFactor(1,2,3) + " \n";
the thing is, unless you are passing parameters to toString, without this, this code seems very limited. Alternatively you need to set some fields on the class with what will be passed into your function.