For this part of my recursive method I need to handle the case of an even length string greater than 2 (as shown in my base cases). My issue is figuring out how to make my recursive case actually approach my base cases. I'm not sure if I did the reversing part correctly either, as I get a Stack Overflow error due to the base cases never being hit.
Here's the method in question. (I will handle the odd Strings after my current 'if' statement. I have "return null;" there at the moment so I can test my even case without the odd.)
EDIT:
Example input: ABCDEF
Example output: EBCDAF
public static String revEven(String inString)
{
String tempString = new String();
if (inString.length() <= 2)
return inString;
if (inString.length() == 3)
{
tempString += inString.charAt(2);
tempString += inString.charAt(1);
tempString += inString.charAt(0);
return tempString;
}
if (inString.length() % 2 == 0)
{
return revEven(inString.substring(0, inString.length() - 1) + inString.charAt(inString.length() - 1));
}
return null;
}
The reason why you get StackOverflowError is that your string doesn't change between recursive calls. In the line where you call the function again you just recreate initial string.
"ABCD" = "ABC" (substring (0,3)) + "D" (charAt(3)) - the same string.
Hint. Don't try to change the string in recursive calls.
Probably, it's better to represent your string as array of chars, change indices in recursive calls and then swap chars in place which are pointed by even indices.
I didn't check corner cases but the idea is below:
public static String runEven(String string) {
char[] array = runEvenImpl(string.toCharArray(), 0, string.length());
return new String(array);
}
public static char[] revEvenImpl(char[] array, int head, int tail) {
if (head == tail)
return array;
if (head % 2 == 0 && tail % 2 == 0)
{
swap(array, head, tail);
}
revEven(array, head+1, tail-1);
}
Related
So, the task is to create a string that makes a progression throughout the letters of a string, returning a substring progressively longer.
For example if the input is Book, the answer would be: BBoBooBook . For the input Soup the method would return SSoSouSoup. I want to write it recursively. In my current method I receive no error but at the same time no anwer from the compiler.
public static String stringProgression(String str) {
int index = 1;
String result = "";
if (str.length() == 0) {
return "" ;
} else while (index <= str.length()); {
result = result + stringExplosion(str.substring(0, index));
index++;
}
return result;
}
In your code, you are using two different method names, stringProgression and stringExplosion.
Further, you have a while loop with a semicolon, while (index <= str.length()); which forms an empty loop. Since index doesn’t change in this empty loop, it will be an infinite loop when the condition is fulfilled.
Generally, a while loop contradicts the intent to have a recursive solution.
To find a recursive solution to a problem, you have to find the self-similarity in it. I.e. when you look at the intended result for Book, BBoBooBook, you can recognize that the beginning, BBoBoo is the right result for the string Boo, and BBo is the right result for Bo. So, the original string has to be appended to the result of a recursive evaluation of the substring:
public static String stringProgression(String str) {
if(str.isEmpty()) {
return str;
}
return stringProgression(str.substring(0, str.length() - 1)) + str;
}
An alternative, shorter syntax for the same is:
public static String stringProgression(String str) {
return str.isEmpty()? str: stringProgression(str.substring(0, str.length() - 1)) + str;
}
Check this one:
private static String doStringProgression(String str, String res, int length) {
if(length > str.length()) {
return res;
}
return doStringProgression(str, res + str.substring(0, length), length + 1);
}
And you can call the method with input like in the following example:
public static String stringProgression(String str) {
return doStringProgression(str, "", 1);
}
I am having a hard time figuring out why my code will not work. I am trying to stop the output on a specific letter, but it keeps iterating through the entire string instead. This is what I have,
public static char stringIterator(String string) {
System.out.println(string);//Keep this line
char lastChar = string.charAt(string.length() - 1);
if (lastChar == 'M') {
return lastChar;
}
else if (string.length() == 1) {
return lastChar;
}
else {
return stringIterator(string.substring(0, string.length() - 2));
}
}
if you want to just see if it has it then you would use
string.contains('char');
if you want to traverse/iterate then
for( int i = 0; i < string.length(); i++)
if(string.at(i) == '#')
{ //whatever you want here
}
You might be over-thinking this...
Java has very good resources for dealing with Strings, check out the docs:
Java String Documentation
if (string.contains('m')){
//dostuff
}
if (string.endsWith('m')){
//dostuff
}
etc.
As for your iteration problem, you'll have to post the rest of your code, as it looks like your Loop is Calling stringIterator(String) from somewhere outside this method.
(It's not really a stringIterator if it doesn't iterate anything)
Also this last line of code:
return stringIterator(string.substring(0, string.length() - 2));
Is recursive (calls itself)... which can cause you trouble. There's certainly uses for recursion, finding something in a 1d array is not one of those uses. Assuming your loop is working properly this could be what's preventing you from stopping the output.
public String substring(int begIndex, int endIndex) - returns a new string that is a substring of the string
Parameters :
beginIndex : the begin index, inclusive.
endIndex : the end index, exclusive.
(eg): String string = "NAME"
string.substring(0, string.length() - 2) - returns "NA"
string.substring(0, string.length() - 1) - returns "NAM" . Use this, thus you will be able to subtract the last character of the string.
Iterative approach
public static char stringIterator(String string) {
char lastChar = string.charAt(0);
for(int i = string.length()-1 ;i>=0;i--) {
System.out.println(string);//Keep this line
lastChar = string.charAt(i);
if (string.length() == 1 || lastChar == 'M') {
break;
} else {
string = string.substring(0, i);
}
}
return lastChar;
}
I am trying to figure out how to search a string for a certain number then if that number exists in the string do the following:
String str = "String4";
int myInt = 0;
public static void checkString(String str) // FIX ME
{
if(str.indexOf('3') == 0)
{
myInt = 3;
}
else if(str.indexOf('4') == 0)
{
myInt = 4;
}
else if(str.indexOf('5') == 0)
{
myInt = 5;
}
}
This never returns true though, is there an alternative way to search the string. There is a lot of extra code, but this method is the only thing causing the problem. I am pulling my hair out because of it, some help would be much appreciated!
For example
if(str.indexOf('3') == 0)
search everytime 3 at position 0, it's not appropriate, because digit can be everywhere in string.
Use instead
str.indexOf('3')!=-1
and retrieve position with return value of indexOf
Check if a substring is in the given string using the contains method.
public static void checkString(String str)
{
if(str.contains("3"))
myInt = 3;
else if(str.contains("4"))
myInt = 4;
else if(str.contains("5"))
myInt = 5;
}
Let's start with an explanation of your approach before we get to an answer.
Starting with your string String str = "String4", I'm assuming that you pass it to checkString().
The indexOf() function for a string searches the string for a substring (a character in your case) and returns its position, indexed from 0. For example, if you call str.indexOf("t") it will return 1 because the character t is in position 1. Therefore, in your code you check if the numbers 3, 4, and 5 reside in the strings index 0 (the first character).
If you want to use indexOf() for this function, you can check if the number is in the string in the first place. IndexOf() returns -1 if the character your searching for isn't in the string, so you can use the following:
if (str.indexOf("3") != -1){
//do your stuff
}
And the same for 4 and 5.
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.
I am stuck on this CodingBat recursion problem:
Given a string, return recursively a "cleaned" string where adjacent chars that are the same have been reduced to a single char. So "yyzzza" yields "yza".
stringClean("yyzzza") → "yza"
stringClean("abbbcdd") → "abcd"
stringClean("Hello") → "Helo"
I can solve it using loops, but this is not allowed since the problem is supposed so be solved using recursion. Is there any way to solve this problem without using a loop and using only recursion? No global variables, no loops. I even thought of encoding some information in the parameter but that would be cheating too I think.
My previous program had no while loop, and I could only get half of the answers right. Basically, when I called my function with the string parameter, I checked the first 2 characters. If they were the same, I would return the character and call the function again with a string two characters smaller. A string of 3 or 4 of the same consecutive characters would always defeat my algorithm however.
public String stringClean(String str) {
if (str.length() == 0)
return "";
if (str.length() > 1) {
int counter = 1;
char a = str.charAt(0);
char b = str.charAt(1);
if (a == b)
{
while (str.length() > 1)
{
a = str.charAt(0);
b = str.charAt(1);
if (a != b) break;
counter++;
str = str.substring(1);
}
return a + stringClean( str.substring(1) ) ;
}
}
return str.charAt(0) + stringClean (str.substring(1) );
}
My question is the following, is there any way to solve this problem without using a loop and using only recursion. No global variables, no loops.
Answer: Yes. It is very simple. Try below:
public String stringClean(String str) {
if (str.length() == 0)
return "";
if (str.length() == 1)
return str;
if(str.charAt(0) == str.charAt(1)){
return stringClean(str.substring(1));
}else{
return str.charAt(0)+ stringClean(str.substring(1));
}
}
Your CodingBat results in below:
stringClean("yyzzza") → "yza" "yza" OK
stringClean("abbbcdd") → "abcd" "abcd" OK
stringClean("Hello") → "Helo" "Helo" OK
stringClean("XXabcYY") → "XabcY" "XabcY" OK
stringClean("112ab445") → "12ab45" "12ab45" OK
stringClean("Hello Bookkeeper") → "Helo Bokeper" "Helo Bokeper" OK
other tests OK
My question is the following, is there any way to solve this problem without using a loop and using only recursion. No global variables, no loops.
The answer is "yes it is possible".
Hints:
Like most "tricky" recursive problems this requires an extra parameter.
Think of the problem as filtering the first character of the string at each stage.
The first character of the input string is a special case ...
public String stringClean(String str) {
if (str == null) {
return null;
} else if (str.length() > 1) {
String k = str.substring(0, 1);
if (str.charAt(0) == str.charAt(1)) {
String tmp = stringClean(str.substring(2));
return k + stringClean(tmp);
} else {
return k + stringClean(stringClean(str.substring(1)));
}
} else {
return str;
}
}
Here is my answer
public String stringClean(String str) {
if(str.isEmpty()) return "";
if(str.length()==1)return str;
if(str.length() > 1 && !str.substring(0,1).equals(str.substring(1,2)))
return str.substring(0,1) + stringClean(str.substring(1));
return ""+stringClean(str.substring(1));
}