Flipping binary numbers using recursion - java

I am working on a project that the user enters an odd binary number ex: 10101 and I am supposed to have a recursive method that will flip the 1's and 0's ex: 101 = 010. For some reason my code is getting rid of the leading zero making the number an even number which crashes the program. Any and all help is appreciated, below is my Recursive class that is supposed to do the work of flipping the binary digits.
public class Recursive2 {
// int digit;
String temp;
public Recursive2(int d){
//digit = d;
temp = recursive(Integer.toString(d));
//System.out.print(recursive(temp));
}
public String toString(){
return temp;
}
public String recursive(String a){
String tempStr = "";
if(a.length() % 2 == 0){
System.out.println("Even number");
return "";
}
else if(a.length() == 1){
if(a.equals("1")){
tempStr = "0";
// tempStr += d;
}
else if(a.equals("0")){
tempStr= "1";
}
//System.out.println("Flipped d to" + tempStr);
}
else{
tempStr += new Recursive2(Integer.parseInt(a.substring(0,1))).toString();
tempStr += new Recursive2(Integer.parseInt(a.substring(1, a.length() - 1))).toString();
tempStr += new Recursive2(Integer.parseInt(a.substring(a.length()-1, a.length()))).toString();
}
return tempStr;
}
Here is my main class that tests the recursion.
public static void main(String[] args){
String num;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a Binary number with an odd amount of digits: ");
num = in.nextLine();
System.out.println(num);
int num2 = Integer.parseInt(num);
System.out.println(num2);
Recursive2 test = new Recursive2(num2);
System.out.println(test);
}

You made several mistakes:
Deciding if the number is odd or even should be done before calling recursive method. Currently, your code will stop after at most one invocation, because you check the number of bits.
There is no need to parse int and making it String again. The entire process can be done entirely with strings.
Constructing the result should consist of appending the result of recursive invocation without the last bit to the string representing the inverse of the last bit.
The base case should be a situation when the string is empty, not when the string has exactly one digit.
Fixing these mistakes will produce a correct implementation.

The current algorithm is beyond repair.
Here's a recursive algorithm that's very simple and that will work:
if the string is empty, return it
if the first char is 0, return "1" + recurse(s.substring(1))
otherwise (the first char is 1), return "0" + recurse(s.substring(1))

Leading zeros are ignored because you're converting the input binary number to integer. For an integer leading zeros don't mean anything. You should be working with String only.
Also Integer.parseInt(num); would assume that you want to parse a decimal number not binary. If you do want to parse a binary number then you'll have to use another overloaded method Integer.parseInt(String s, int radix)
However as I said, because of the leading zeros you should work only with the Strings.

Integer.parseInt(i) converts the String to its Integer value.
However the Integer value of 010 is 10, leading 0's are dropped.
Work with the input as a String to avoid this.

Use StringBuilder to avoid creating new String or you can use char array
public static void main(String[] args) {
int no = 1234; // some no
String in = Integer.toBinaryString(no);
System.out.println("Original " + in);
System.out.println("Flipped " + flipBits(in));
}
public static String flipBits(String in) {
if (in.length() % 2 == 0)
return "even length";
return new String(flipBits(in.toCharArray(), in.length() - 1));
}
private static char[] flipBits(char[] ch, int index) {
if (index < 0) {
return ch;
} else {
ch[index] = Character.forDigit(49 - ch[index], 2); //flip
return flipBits(ch, index - 1);
}
}
output
Original 10011010010
Flipped 01100101101

The problem is that you are converting to integer values, which will throw away leading zeros. Just deal with strings:
public static void main(String[] args){
String num;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a Binary number with an odd amount of digits: ");
num = in.nextLine();
System.out.println(num);
String flipped;
if (num.length() % 2 == 0) {
flipped = "Even number";
else {
flipped = Recursive2.recursive(num);
}
System.out.println(flipped);
}
And the Recursive2 class can just have static methods:
public class Recursive2 {
private static String flip(char c) {
if (c == '0') return "1";
return "0"; // assumes characters are all 0 or 1
}
public static String recursive(String a) {
STring tempStr;
if (a.length() == 0) {
tempStr = "";
} else {
tempStr = flip(a.charAt(0)) + recursive(a.substring(1));
}
return tempStr;
}
}
You might want to throw an exception if you detect a character other than 0 or 1.
EDIT: Based on your comment, the recursive method can be written as:
public static String recursive(String a) {
String tempStr = flip(a.charAt(0));
final int len = a.length();
if (len > 1) {
tempStr += recursive(a.substring(1, len - 1)) + flip(a.charAt(len - 1));
}
return tempStr;
}
This assumes that the argument is an odd-length string. That check should be done outside the recursive method, since if it is true once, it is true at every subsequent recursion.

I'd advise you to instead, remove one digit from the String that the user has imputed, and convert it (from the 1 to 0 vise versa), then use sub-string as the pass for the recursive function with one less.
Hint-> the base case would be a.length() == 0; because if you remove one digit of the string you will eventually have the length be 0.
Good Luck!

Related

How does recursion work and how can recursion be used to manipulate integer digits?

I'm trying to learn java, and I can't seem to understand recursion. I can understand how recursion can be used to add and do other basic math operations but how can recursion be used to reverse manipulate integers and individual integer digits.
example:
a method takes a single positive integer argument and displays its base five equivalent. 231 returns 1411 but the code below returns 1141. how would I reverse the order of integers put out?
public void base5(int n){
int rem=n%5;
int vis=n/5;
if(n!=0){
// System.out.print(rem/*+"|"*/);
//
// rem=(rem+rem)*10;
// System.out.print("\n||"+n+"||\n");
System.out.print(rem);
base5(vis);
}
else{
return;
}
}
The algorithm for getting individual digits of an integer, from right to left, is well known. See How to get the separate digits of an int number?.
I won't "explain" recursion, but I'll give you one possible solution for first problem:
a method takes a single positive integer and displays it with commas
inserted every three digits
import java.util.Scanner;
class Main {
public static void main( String [] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter your positive integer: ");
long number = sc.nextLong();
String result = addCommas(number);
System.out.println(result);
}
public static String addCommas(long num) {
return addCommas(num, 1);
}
public static String addCommas(long num, int counter) {
if (num == 0) {
return ""; // base case ends recursion
}
else {
long digit = num % 10;
num = num / 10;
String comma = (counter%3==0 && num>0) ? "," : "";
// recursive call below because we call addCommas() again
return addCommas(num, counter+1) + comma + digit;
}
}
}
Here's a compact solution to the second problem:
a method takes a single positive integer and displays the result of
reversing its digits
public static String reverseDigits(long num) {
if (num == 0) {
return "";
}
else {
return String.valueOf(num % 10) + reverseDigits(num / 10);
}
}

Unable to run Palindrome program in Java [duplicate]

This question already has answers here:
Check string for palindrome
(42 answers)
Closed 2 years ago.
Here's my Java code to find a palindrome of a string. It shows o/p as "Palindrome" even though the i/p that I've entered is not. Can anyone please help.
String a = sc.next();
char b[] = a.toCharArray();
char d[] = b;
int size = a.length();
int beg=0,end=size-1;
while(beg<=end)
{
char temp = b[beg];
b[beg] = b[end];
b[end] = temp;
beg++;
end--;
}
if(d.equals(b))
{
System.out.print("Palindrome");
}
else
System.out.print("Not a Palindrome");
There are a few problems with your implementation. First of all -
while(beg<=end)
{
char temp = b[beg];
b[beg] = b[end];
b[end] = temp;
beg++;
end--;
}
Debug carefully and see do you really have d[] as the reverse of b[] at the end of this while loop
Secondly,
if(d.equals(b))
{
System.out.print("Palindrome");
}
This is not the correct way to compare if all the array elements are same in both of the array. If you look into the implementation or try out with some sample array you will be able to see it yourself.
To check palindrome, very simple approach is to reverse the string using StringBuilder and check if it's equal to the original string -
Scanner sc = new Scanner(System.in);
String a = sc.next();
String aRev = new StringBuilder(a).reverse().toString();
if (a.equals(aRev)) {
System.out.print("Palindrome");
} else {
System.out.print("Not a Palindrome");
}
Another better approach is to run a loop from beginning to middle of the string and keep an index from end to middle. Then check both forward index and backward index.
Scanner sc = new Scanner(System.in);
String a = sc.next();
boolean palindrome = true;
for (int i = 0; i < a.length() / 2; i++) {
if (a.charAt(i) != a.charAt(a.length() - i - 1)) {
palindrome = false;
break;
}
}
System.out.println(palindrome ? "Palindrome" : "Not Palindrome");
With
char d[] = b;
you create the alias d for b. So, in essence, b and d refer to the same char-Array. There is no difference beween modifying b and modifying d. Therefore, the comparison d.equals(b) will always yield true.
Try this code, it works as expected.
public class Main {
public static boolean isPalindrome(String str) {
int i = 0, j = str.length() - 1;
// The following condition checks if the decreasing index
// is larger than the increasing one,
// which happens at the middle of the string.
// This is done, because there is no need to iterate over,
// the entire string.
while(j > i){ // Non-matching character found, return early.
if(str.charAt(i) != str.charAt(j)){
return false;
}
j--; // Ending index decreases.
i++; // Starting index increases.
}
// If the loop finishes, without returning all characters of the string match.
return true;
}
public static void main(String[] args) {
String string = "Non-palindrome";
String palindrome = "WoW";
System.out.println("String " + string + " is palindrome: " + isPalindrome(string));
System.out.println("String " + palindrome + " is palindrome: " + isPalindrome(palindrome));
}
}
When run, the above code outputs:
String Non-palindrome is palindrome: false
String WoW is palindrome: true

keep leading zeros only while reversing a number in java

I am doing my assignment question which is to "reverse a number keep the leading zeros and remove the trailing zeros also keep the sign as it is".
If I reverse it taking as a integer, it will remove leading as well as trailing zeros and if I reverse it taking as a string, it will keep all the zeros.
Can anyone help me only keeping the leading zeros.
For example "-00360" should be "-6300".
problem-
Write a Java function to accept a number and return the reverse of the same. If the number ends with one or more zeros, then in the reversed number those zeros will not be present (since those zeros become leading zeros). If the input number is negative, the sign should be retained. ##Examples Input: -123 Output: -321 Input: 1123400 Output: 43211
In below codes, you can reverse the negative and positive numbers. On method reversedString(String num), you can reverse your numbers. String reverseNumKeeper() helps you to keep your new reversed number. With using for loop, you reverse the number, 123 => 321. Then, you should check if the new reversed String has a negative sign, if has, you should add it in front of number, else, just return new reversed number.
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter number");
//input
String number = scanner.next();
System.out.println(Reverse.reversedString(number));
}
private static String reversedString(String num) {
String reverseNumKeeper = "";
//reverse number with and without negative sign
for (int i = num.length(); i > 0; i--) {
reverseNumKeeper += num.charAt(i - 1);
}
//check if reverseNumKeeper has a negative sign or not
if (reverseNumKeeper.contains("-")) {
return "-" + Integer.parseInt(reverseNumKeeper.replace("-", ""));
} else {
return "" + Integer.parseInt(reverseNumKeeper);
}
}
}
Well as YCF_L said you can just use a StringBuilder having a negative there does not make to much difference. You can include a check for it.
public class FunWithNumbers {
public static int numberReverser(String number) {
System.out.println("Input: " + number);
int returnVal;
String returnString;
boolean negative = false;
//If minus is always at the start if it is there
if(number.substring(0, 1).equals("-")) {
negative = true;
}
if(negative) {
returnString = new StringBuilder(number.substring(1, number.length() - 1)).reverse().toString().replaceFirst("^[0]+", "");
returnString = "-" + returnString;
} else {
returnString = new StringBuilder(number).reverse().toString().replaceFirst("^[0]+", "");
}
try {
returnVal = Integer.parseInt(returnString);
} catch (NumberFormatException nFE) {
System.out.println("There was a number format exception");
returnVal = -1;
}
System.out.println("Output: " + returnVal + "\n");
return returnVal;
}
public static int numberReverser(int number) {
return numberReverser(Integer.toString(number));
}
public static void main(String[] args) {
//Usage
FunWithNumbers.numberReverser("003600");
FunWithNumbers.numberReverser("-003600");
FunWithNumbers.numberReverser((int)0036000D);
FunWithNumbers.numberReverser((int)-003600D);
}
}
Output
Input: 003600
Output: 6300
Input: -003600
Output: -6300
Input: 36000
Output: 63
Input: -3600
Output: -63
You might notice that there are two ways of inputting it here, but only one will give you the correct output you are after.
The first way if with a String. This provides the expected output. The second method, with an int does not provide the expected output. This is because an int will not store the leading zeros. Similarly, if you attempt to input an int with leading zeros, you can actually convert it to octal. To avoid this you can use (int)<int>D or (int)<int>F. See the example in the code

What's the best method of finding integers in a string?

Hello StackOverflow community! I'm student trying to solve this problem....
The main issue I am having with it is that I dont know the best way to find characters that are valid integers in Strings.
Note: I am only 1 month into learning Java, and I spent most of last year learning python. So compiler languages are new to me.
Write a program that reads in a product code and outputs whether it is valid or not based on some simple rules.
The rules:
1st part can contain only capital letters and 6 digits. 2nd part is alldigits and = the product of the first 6 digits taken in groups of two from the left.
eg: AX6BYU56UX6CV6BNT7NM 287430
is valid because 65*66*67 = 287430
This is what I have so far
import java.util.*; //import java utilities
public class Basic5{ //declares my class
public static void main(String[]args){
Scanner kb=new Scanner(System.in);//creates Scanner for user input
String userentry=kb.nextLine(); //Takes users input as a string
String result="Valid"; //Variable for if the code is Valid
int DoubleCounter=0; //Counter for number of ints
double newdouble;
List<Double> NumberList = new ArrayList<Double>(); //Creates Array List for tracking Doubles
for(int i=0;i<userentry.length();i++){ //checks length of Users input
if(Character.isLowerCase(userentry.codePointAt(i))){ //checks if its a Lowercase letter
result="Fail"; //Changes result variable
if(Integer.parseInt(userentry,i)){ //checks if character from input is a valid integer
DoubleCounter+=1; //Adds to DoubleCounter
newdouble=userentry.charAt(i); //Isolates character
NumberList.add(newdouble); //Adds it to List of doubles
}
}
}
}
}
You can use following methods to check whether the input is a char or digit :
Character.isDigit('A');
Character.isLetter('A');
Here's one way to do it:
#Test
public void testExample() {
assertTrue(isValid("AX6BYU56UX6CV6BNT7NM 287430"));
assertFalse(isValid("AX6BYU56UX6CV6BNT7NM 287431"));
}
private boolean isValid(String s) {
String[] parts = s.split(" ");
int[] ints = extractIntegers(parts[0]);
int target = Integer.parseInt(parts[1]);
return product(ints) == target;
}
private int[] extractIntegers(String s) {
String digits = s.replaceAll("\\D+", "");
int[] ints = new int[digits.length() / 2];
for (int i = 0; i < digits.length(); i += 2) {
ints[i / 2] = Integer.parseInt(digits.substring(i, i + 2));
}
return ints;
}
private int product(int[] ints) {
int result = 1;
for (int num : ints) {
result *= num;
}
return result;
}
It assumes that there are non-zero even number of digits in the first part of the string. If you need to handle other cases, it should be easy to do, based on this.
String str = "AX6BYU56UX6CV6BNT7NM 287430";
str = str.replaceAll("[^0-9]+", "");

Scanner only reading first set of input

This is a code I have developed to separate inputs by the block (when a space is reached):
import java.util.Scanner;
public class Single {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Three Numbers:");
String numbers = in.next();
int length = numbers.length();
System.out.println(length);
int sub = length - length;
System.out.println(sub);
System.out.println(getNumber(numbers, length, sub));
System.out.println(getNumber(numbers, length, sub));
System.out.println(getNumber(numbers, length, sub));
}
public static double getNumber(String numbers, int length, int sub){
boolean gotNumber = false;
String currentString = null;
while (gotNumber == false){
if (numbers.substring(sub, sub + 1) == " "){
sub = sub + 1;
gotNumber = true;
} else {
currentString = currentString + numbers.substring(sub, sub);
sub = sub + 1;
}
}
return Double.parseDouble(currentString);
}
}
However, it only reads the first set for the string, and ignores the rest.
How can I fix this?
The problem is here. You should replace this line
String numbers = in.next();
with this line
String numbers = in.nextLine();
because, next() can read the input only till the first space while nextLine() can read input till the newline character. For more info check this link.
If I understand the question correctly, you are only calling in.next() once. If you want to have it process the input over and over again you want a loop until you don't have any more input.
while (in.hasNext()) {
//do number processing in here
}
Hope this helps!

Categories