Using recursion to add 0 after every even digit - java

Hello guys,
I would like to share with you my problem. I am practicing recursive methods and i have noticed somewhere one exercise. The exercise is about making the recursive method which adds a 0 to every even digit. If someone has some idea, it would be great if you share here.
the code would be something like this :
public static String adding0AfterEvenNumber(int number) {
String s = String.valueOf(number);
String result;
if (number < 10 && number % 2 == 0) {
return s + 0;
}
}
I am missing the main part of the code but i really do not have an idea how to create it. Thanks in advance

consider this code (comments in line)
// somewhere to store the result
static StringBuilder result = new StringBuilder();
public static void main(String [] args) {
// starting string
String s = "1234567";
// or as
//String s = Integer.toString(1234567);
// call with full string
recurse (s);
// print result
System.out.println("result : " + result.toString());
}
private static void recurse(String s) {
// take first char and add to result
String c = s.substring(0,1);
result.append(c);
// see if even, note no error checking for is a number
if (Integer.parseInt(c) % 2 == 0) {
result.append("0");
}
// then if still has content then strip off first char and call again
if (s.length() > 1)
recurse(s.substring(1));
}
output
result : 1203405607

You would recurse something like this:
public static String adding0AfterEvenNumber(int number) {
return ((number >= 10) ? adding0AfterEvenNumber(number / 10) : "") + String.valueOf(number % 10) + ((number % 2 == 0) ? "0" : "");
}
Try it here.
<script src="//repl.it/embed/JDEV/1.js"></script>
The first part is the terminal condition, appending nothing if there is a single digit number, else calling the recursion after removing the last digit:
(number > 10) ? adding0AfterEvenNumber(number / 10) : "")
The second part appends a zero to the last digit, if even:
String.valueOf(number % 10) + ((number % 2 == 0) ? "0" : "")

I understand that even digits are those digits with an even value not in an even position. The following function should return you a string with the value, although you could return an integer if you shift the head value as many digits as the tail has.
public String add0onEven(int number, int initPos, int endPos) {
if (initPos == endPos - 1) {
int digit = (number / (int) Math.pow(10, initPos)) % 10;
if (digit % 2 == 1) {
return digit + "0";
} else {
return "" + digit;
}
} else if (endPos - initPos < 1) {
return "";
} else {
int sepIdx = (endPos - initPos) / 2 + initPos;
String tail = add0onEven(number, initPos, sepIdx);
String head = add0onEven(number, sepIdx, endPos);
return head + tail;
}
}
You can call the method like this:
add0onEven(1234567, 0, 7)
The output obtained for this invocation:
10230450670
I believe this solution to be better than the substring ones for its lower impact on memory (No need to create a new string on each substring invocation). Besides, it follows a Divide and Conquer approach that suits better to recursivity.

Related

Cant remove all chars from a string before a "special one"

I tried coding a complete decimal to binary converter, which worked just fine and now I want to remove the unnecessary 0s from my output String, but it doesnt remove all of the 0s and I have no idea why.
Here is my code :
public class Converter {
private static final int[] ARRAY = {16348,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};
public static String toBinary(int number) {
String output = new String();
int number2 = number;
for (int i=0; i<ARRAY.length ; i++) {
if (number2 - ARRAY[i] >= 0) {
output += "1";
number2 -= ARRAY[i];
}
else {
output += "0";
}
}
boolean sorted = false;
int i = 0 ;
while (sorted == false) {
if (output.charAt(i) == '0') {
StringBuilder temp = new StringBuilder(output);
temp.deleteCharAt(i);
output = temp.toString();
i ++;
}
else{
sorted = true;
}
}
return output;
}
}
It's because the variable i is pointing to a wrong location. It's because after you remove the 0 at the ith you are incrementing i.
For example, take the string 00001 (a minified one in terms of number of bits)
When i = 0, after removing the 0 at index i we get 0001. On incrementing i becomes 1.
When i = 1, after removing the 0 at index i we get 001. On incrementing i becomes 2.
(We have already skipped past the first 0).
Removing i++ will do the trick. Still, your code does not work for input 0. In your while loop, you still need to validate the index i and break the while loop by checking if output string is empty.
A simple solution would be to use Integer.valueOf as suggested in this answer.
Or another one-liner would be:
String result = output.contains("1") ? output.substring(output.indexOf("1")) : "0";
I suggest to use simpler solution to remove trailing zero's by parsing the output to Integer
use this
int x = Integer.valueOf(output);
// if you wanted the output as string
String val = String.valueOf(x);
It is preferable that you don't add the leading zeroes in the first place. Why create, then remove? This method will not add leading zeroes until a one has been detected:
public static String toBinary(int number) {
String output = new String();
int number2 = number;
boolean foundOne = false;
for (int i=0; i<ARRAY.length ; i++) {
if (number2 - ARRAY[i] >= 0) {
output += "1";
number2 -= ARRAY[i];
foundOne = true;
}
else if (foundOne){
output += "0";
}
}
if (!foundOne)
output = "0";
return output;
}
String s = "00010101"
System.out.println(s.replaceAll("^0*", ""))
// => 10101
This is a example using regex.
^ means the expression should only match at the beginning of a string.
0*matches any string of characters that repeats 0 zero or more times

Recursively decompressing a String

I have this assignment that needs me to decompress a previously compressed string.
Examples of this would be
i4a --> iaaaa
q3w2ai2b --> qwwwaaibb
3a --> aaa
Here's what I've written so far:
public static String decompress(String compressedText)
{
char c;
char let;
int num;
String done = "";
String toBeDone = "";
String toBeDone2 = "";
if(compressedText.length() <= 1)
{
return compressedText;
}
if (Character.isLetter(compressedText.charAt(0)))
{
done = compressedText.substring(0,1);
toBeDone = compressedText.substring(1);
return done + decompress(toBeDone);
}
else
{
c = compressedText.charAt(0);
num = Character.getNumericValue(c);
let = compressedText.charAt(1);
if (num > 0)
{
num--;
toBeDone = num + Character.toString(let);
toBeDone2 = compressedText.substring(2);
return Character.toString(let) + decompress(toBeDone) + decompress(toBeDone2);
}
else
{
toBeDone2 = compressedText.substring(2);
return Character.toString(let) + decompress(toBeDone2);
}
}
}
My return values are absolutely horrendous.
"ab" yields "babb" somehow.
"a" or any 1 letter string string yields the right result
"2a" yields "aaaaaaaaaaa"
"2a3b" gives me "aaaabbbbbbbbbbbbbbbbbbbbbbbbbbaaabbbbaaaabbbbbbbbbbbbbbbbbbbbbbbbbb"
The only place I can see a mistake in would probably be the last else section, since I wasn't entirely sure on what to do once the number reaches 0 and I have to stop using recursion on the letter after it. Other than that, I can't really see a problem that gives such horrifying outputs.
I reckon something like this would work:
public static String decompress(String compressedText) {
if (compressedText.length() <= 1) {
return compressedText;
}
char c = compressedText.charAt(0);
if (Character.isDigit(c)) {
return String.join("", Collections.nCopies(Character.digit(c, 10), compressedText.substring(1, 2))) + decompress(compressedText.substring(2));
}
return compressedText.charAt(0) + decompress(compressedText.substring(1));
}
As you can see, the base case is when the compressed String has a length less than or equal to 1 (as you have it in your program).
Then, we check if the first character is a digit. If so, we substitute in the correct amount of characters, and continue with the recursive process until we reach the base case.
If the first character is not a digit, then we simply append it and continue.
Keep in mind that this will only work with numbers from 1 to 9; if you require higher values, let me know!
EDIT 1: If the Collections#nCopies method is too complex, here is an equivalent method:
if (Character.isDigit(c)) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Character.digit(c, 10); i++) {
sb.append(compressedText.charAt(1));
}
return sb.toString() + decompress(compressedText.substring(2));
}
EDIT 2: Here is a method that uses a recursive helper-method to repeat a String:
public static String decompress(String compressedText) {
if (compressedText.length() <= 1) {
return compressedText;
}
char c = compressedText.charAt(0);
if (Character.isDigit(c)) {
return repeatCharacter(compressedText.charAt(1), Character.digit(c, 10)) + decompress(compressedText.substring(2));
}
return compressedText.charAt(0) + decompress(compressedText.substring(1));
}
public static String repeatCharacter(char character, int counter) {
if (counter == 1) {
return Character.toString(character);
}
return character + repeatCharacter(character, counter - 1);
}

Finding sequences of characters, whichever's first

I wrote a code that finds four different sequences of characters.
ATG is always at the start and TAG, TGA or TAA are the "stop" sequences.
The number of characters in between START and STOP sequences should by a multiple of 3.
For example in the following String: ACCATGCCCTAGTTT my program returns ATGCCCTAG.
And in this string: AAATGCCTAGTTAA the program returns ATGCCTAGTTAA, because the number of characters between ATG and TGA is not a multiple of three, so it looks for the next "stop" sequence, which is TAA in this case.
Here's the code:
public class TagFinder {
public String findProtein(String dna) {
String fpL = dna.toLowerCase();
int start = fpL.indexOf("atg");
int stop = fpL.indexOf("tag", start+3);
int stop2 = fpL.indexOf("tga", start+3);
int stop3 = fpL.indexOf("taa", start+3);
if (start == -1) {
return "";
}
if ((stop - start) % 3 == 0) {
return fpL.substring(start, stop+3);
}
if ((stop2 - start) % 3 == 0) {
return fpL.substring(start, stop2+3);
}
if ((stop3 - start) % 3 == 0) {
return fpL.substring(start, stop3+3);
}
else {
return "";
}
}
However, In the following String "ATTATGCCCTAATAG", the code will first find ATGCCCTAATAG, even though TAA is the first "stop" sequence in the string and the number of chars between ATG and TAA is 3.
How can I write this program, so that whichever "STOP" sequence appears first in the string and is n3 away from the start sequence is returned.
Thank you.
Regular expressions will do.
String input = "ACCATGCCCTAGTTT";
String expected = "ATGCCCTAG";
Pattern pattern = Pattern.compile("(ATG)(.{3})*?(TAG|TGA|TAA)",
Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(input);
while (m.find()) {
System.out.printf("[%d] %s%n", m.start(), m.group());
}
In the above the start position is not necessarily a multiple of 3. If the start position must be a multiple of 3, then it would easiest to make groups of 3 letters and a separator.
input = input.replaceAll(".{3}", "$0,");
Pattern pattern = Pattern.compile("(ATG,)(.{4})*?(TAG|TGA|TAA),",
Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(input);
while (m.find()) {
System.out.printf("[%d] %s%n", m.start() * 3 / 4, m.group().replace(",", ""));
}
You need to determine the minimum of all stop tags, so I'd write something like this:
[...]
int minStop = MAXINT;
if ((stop - start) % 3 == 0 && minStop > stop) {
minStop = stop;
}
if ((stop2 - start) % 3 == 0 && minStop > stop2) {
minStop = stop2;
}
if ((stop3 - start) % 3 == 0 && minStop > stop3) {
minStop = stop3;
}
if (minStop < MAXINT) {
return fpL.substring(start, minStop+3);
} else {
[...]
}
From
if ((stop - start) % 3 == 0) {
return fpL.substring(start, stop+3);
}
It first finds TAG and the return statement is called. If you really want to find the first stop point, add some comaprison logic between stop, stop2 and stop3 to find which is the smallest index. Then do the % 3 check for each and return from the first one that is ok, or the whole string if there is not a valid case. Also how about using a regular expression for this problem ? Something in the lines of (ATG)\w{3}(TAG|TGA|TAA).
The following code uses a list of any search words, then selects the minimum matched index.
public String findProtein(String dna) {
String fpL = dna.toLowerCase();
int start = fpL.indexOf("atg");
List<String> searchWords = new ArrayList<>();
searchWords.add("tag");
searchWords.add("tga");
searchWords.add("taa");
int start = fpL.indexOf("atg");
try{
int startIndex = searchWords.stream().mapToInt(word -> fpL.indexOf(word, 3 + start)).filter(idx -> idx >= 0 && 0 == idx % 3)
.min().getAsInt();
return dna.substring(start, startIndex + 3);
} catch(NoSuchElementException ex) {
return "";
}
}
The reason the code finds "TAG" first is because the way you've written your code:
Your first if statement checks for "TAG". If it finds one, it returns the string between "ATG" and "TAG" and terminates.
What you need to do is create a min variable and store the value of the found terminator codon in this min (after checking it's really min). NOT using returnin the if statements that search for terminator codons. and returning the min + 3 only after the three if statements executed and determined the real minimum distance from "TAG".
Hope it was useful.

Finding Balanced Parenthesis Involving Math

I've tried to solve this question for the past couple of hours and I just don't understand it. I know there must be a sort of mathematical calculation to calculate this but I don't know how to exactly calculate it. I know this code does not make sense because I'm completely lost, I would appreciate any hints or help for this to help me get closer to the solution.
I asked my professor and he told me a hint about it being similar to a permutation/combination using alphabet such as 26^3 for 3 different combinations but this did not help me much.
What I know:
There are 796 characters for the input given in the string and I must find ALL possible ways that 796 characters can be in a balanced parenthesis form.
Since it must start with '(' and end with ')' there must be 2 brackets for each case. So it can be '()()(xc)(cvs)'. Thus that means the mathematical calculation must involve 2*(something) per char(s) since it has to be balanced.
I need to use the remainder(%) operator to recursively find every case but how do I do that when I take a char in not an int?
What I don't know:
How will I analyze each case? Won't that take a long time or a lot of code without a simple formula to calculate the input?
Would I need a lot of if-statements or recursion?
Question:
Let Σ = {), (}. Let L ⊆ Σ* be the set of strings of correctly balanced parentheses. For example, (())() is in L and (()))( is not in L. Formally, L is defined recursively as follows.
ε ∈ L
A string x ≠ ε is in L if and only if x is of the form (y)z, where y and z are in L.
n is a specific 3 digit number between 0 and 999.
Compute f(n) mod 997
Some facts you might find useful: if n1, n2 is a member of N(natural number) then,
(n1 x n2) mod 997 and
(n1 + n2) mod 997
n = 796 (this is specific for me and this will be the given input in this case)
So I must "compute f(796) mod 997 = ?" using a program. In this case I will simply use java for this question.
Code:
import java.util.*;
public class findBrackets
{
public static void main(String[] args)
{
String n;
int answer = 0;
Scanner input = new Scanner(System.in);
System.out.println("Input String");
n = input.nextLine();
// probably wrong because a string can start as x(d))c(()...
for(int i = 0; i < n; i++)
{
if(n[i] != '(' || n[i] != ')' || n[i] != null || n[i] != " ") {
answer = 2 * (Integer.parseInt(n[i]); // how can i calculate if its a char
// i have to use mod % operator somewhere but I don't know where?
}
}
System.out.println("f(796) mod 997 = " + answer);
}
}
You might find the following fact useful: the number of strings of n pairs of balanced parentheses is given by the nth Catalan number and its exact value is
(2n)! / (n! (n + 1)!)
You should be able to directly compute this value mod 997 by using the hint about how products and sums distribute over modulus.
Hope this helps!
I'm still not quite sure exactly what you're asking, but validating as to whether or not the parentheses are valid placement can be done using the following method. I used a similar one to go through hundred-page papers to ensure all parentheses were closed properly in the old days.
public static boolean isValid(String s) {
int openParens = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
// we found an open paren
openParens++;
} else if (s.charAt(i) == ')') {
// we can close a paren
openParens--;
}
if (openParens < 0) {
// we closed a paren but there was nothing to close!
return false;
}
}
if (openParens > 0) {
// we didn't close all parens!
return false;
}
// we did!
return true;
}
You need to do implement this:
public static void main (String[]args) {
String str = "((1+2)*(3+4))-5";
if(isValid(str)){
expandString(str);
}
}
public static boolean isValid(String s) {
int totalParenthesis = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
totalParenthesis++;
} else if (s.charAt(i) == ')') {
totalParenthesis--;
}
if (totalParenthesis < 0) {
return false;
}
}
if (totalParenthesis != 0) {
return false;
}
return true;
}
private static void expandString(String str) {
System.out.println("Called with : "+str);
if(!(str.contains("("))){
evalueMyExpresstion(str);
return;
}
String copyString=str;
int count=-1,positionOfOpen=0,positionOfClose=0;
for(Character character : str.toCharArray()) {
count++;
if(count==str.toCharArray().length){
evalueMyExpresstion(str);
return;
} else if(character.equals('(')) {
positionOfOpen=count+1;
} else if(character.equals(')')) {
positionOfClose=count;
copyString = str.substring(0, positionOfOpen - 1) + evalueMyExpresstion(
str.substring(positionOfOpen, positionOfClose)) + str.substring(positionOfClose + 1);
System.out.println("Call again with : "+copyString);
expandString(copyString);
return;
}
}
}
private static String evalueMyExpresstion(String str) {
System.out.println("operation : "+str);
String[] operation;
int returnVal =0;
if(str.contains("+")){
operation = str.split("\\+");
returnVal=Integer.parseInt(operation[0])+ Integer.parseInt(operation[1]);
System.out.println("+ val : "+returnVal);
return Integer.toString(returnVal);
} else if (str.contains("*")){
operation = str.split("\\*");
returnVal=Integer.parseInt(operation[0])* Integer.parseInt(operation[1]);
System.out.println("* val : "+returnVal);
return Integer.toString(returnVal);
} else if (str.contains("-")){
operation = str.split("\\-");
returnVal=Integer.parseInt(operation[0])- Integer.parseInt(operation[1]);
System.out.println("- val : "+returnVal);
return Integer.toString(returnVal);
}
System.out.println(str);
return Integer.toString(returnVal);
}
Output looks like:
Called with : ((1+2)*(3+4))-5
operation : 1+2
+ val : 3
Call again with : (3*(3+4))-5
Called with : (3*(3+4))-5
operation : 3+4
+ val : 7
Call again with : (3*7)-5
Called with : (3*7)-5
operation : 3*7
* val : 21
Call again with : 21-5
Called with : 21-5
operation : 21-5
- val : 16

Java - Convert decimal to binary - Integer - Recursive function

Hey I'm really trying to convert decimal int to binary int, without succes.
Please help me.
And I don't want to make it 'System.out.println()' becuase I've already done it.
THANKS!
`I need recursive function that gets decimal int and return binary int
public static void decToBin(int number) {
if(number == 0)
return ;
decToBin(number / 2);
System.out.print(number % 2);
}
That it what I've done...
When I'm trying to get string:
public static String decToBin(int number) {
if(number == 0)
return "";
return new Integer(number % 2).toString() + new Integer(decToBin(number / 2)).toString();
}
Error...
public static String decToBin(int number) {
if(number == 0)
return "";
return new Integer(number % 2).toString() + new Integer(decToBin(number / 2)).toString();
}
This approach has few flaws.
First you can't use "" as argument of new Integer("") because "" holds no value, so you will see NumberFormatException.
Other problem is order of generating result. number % 2 should be placed after result of decToBin(number / 2), just like you are doing it in your first example, where you are printing it after recursive decToBin call
decToBin(number / 2);
System.out.print(number % 2);
Lastly in your return statement you are creating new string, so to generate "100101" you will generate "" "1" "01" "101" 0101" "00101" and then finally "100101". To avoid it use StringBuilder and its append method.
This is a little old, but for the sake of reference and giving a correct answer, this is what you would need to do:
public static String dec2Bin(int num) {
String result = ((num % 2 == 0) ? "0" : "1");
if (num == 0 || num == 1) {
return result;
}
return dec2Bin(num/2) + result;
}
void intToBinary(int num) {
if (num < 2) {
System.out.print(num);
return;
} else {
intToBinary(num / 2);
intToBinary(num % 2);
}
}
import java.io.*;
class Binary{
public static void main(String args[])throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the number:");
int n = Integer.parseInt(br.readLine());
System.out.print(Integer.toBinaryString(n));
}
}

Categories

Resources