Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

milk242

macrumors 6502a
Original poster
Jun 28, 2007
695
15
I was wondering if someone could help me go through my wrong logic in this code. I am trying to take a string and remove all the vowels using a recursive method.

Code:
# public static void RemoveVowels(String str)
#      if (str.substring(0,1).compareToIgnoreCase("a" == 0))
#      {
#           str.replace("a", "");
#           RemoveVowels(str.substring(1));
#      }
#      else
#           RemoveVowels(str.substring(1));

My reasoning is that if the character at beginning of string is not "a" then it'll execute the else statement and make the sentence one character shorter. Once it reaches an "a", it'll remove it and make the string one letter shorter.
 

4409723

Suspended
Jun 22, 2001
2,221
0
Why not this:

Code:
public String removeVowels(String s) {
   return s.replaceAll("[aeiou]","");
}

Saves you having to mess around. I see some problems in your logic (strings are immutable and your function is void, etc.) but I need to get out the door in 2 minutes, hope somebody else can help with that.
 

WhiteRabbit

macrumors newbie
Jan 11, 2005
26
0
Shouldn't it be (blah("a") == 0) instead of (blah("a" == 0))?

At some point the string will be only one character. Does the program just crash, what happens then. You might want to check for that.
I don't know Java, but it looks like you're modifying an instance variable in each instance of the method and not returning it.

Also, a recursive fiction seems like an inefficient solution to the original problem.
 

milk242

macrumors 6502a
Original poster
Jun 28, 2007
695
15
Yea I know you can do it with regular expressions or even just use str.replace("a", ""), but I'm working out of a book and I'm on the chapter for recursion. I would just like to figure this out.
 

lazydog

macrumors 6502a
Sep 3, 2005
709
6
Cramlington, UK
Hi

replace() returns a new string, it doesn't do the replacement on the source string itself.

But replace() isn't what you want to use anyway if it's an exercise in recursion. Have a read of the documention for replace() to see why.

b e n
 

aliher

macrumors newbie
Mar 25, 2009
23
0
UK
If you want to build strings you should look on the StringBuilder to build result of your recursion. All string operations create new strings so it may be quite an expensive thing to do that will stress the GC.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I won't write the helper methods, but I would see a recursive solution looking something like this:

Code:
java.lang.String removeVowels(java.lang.String src) {
  if(src == null) return ""; //Base case/input validation
  if(src.length() == 0) return ""; //Base case
  if(src.length() == 1) { //Base case
    if (isVowel(src.charAt(0)) {
      return "";
    } else {
      return src;
    }
  }
  if(isVowel(src.charAt(0)) { //length > 1, recursive case
    return removeVowels(src.substring(1));
  } else {
    return src.charAt(0) + removeVowels(src.substring(1));
  }
}

This isn't the most efficient (at all), since you're going to be building a lot of new Strings that will be immediately discarded. I don't think that's the point of the exercise, though. Obviously there are built in methods for doing this, but the point of this was recursion.

Note that i didn't run this or test it, it could have some devastating bug in it... but that should be the general idea. The way I approach recursion (the few times i do so in iterative languages) is to clearly chart out error cases and base cases and decide how to deal with them. Just because you don't think a String with 0 length will be passed in doesn't mean this shouldn't be handled cleanly. Once you've mapped out your base cases, then you have to deal with your recursive case. At this point some amount of work should be done, and "less" work should be passed to a new instance of your function.

Note that in a language that doesn't implement zero stack growth tail recursion, you're using a chunk of memory each time you hit your recursive case. This means that if you have a String that's a few thousand characters long, you may start running into issues with the stack. I'm not sure how the JVM will deal with this, to be honest. It may grow the stack space, and you'll have room up until the maximum memory, it may throw an OutOfMemory exception or something, etc. Just something to be aware of.

-Lee

EDIT: There was quite a bit of discussion about stack growth here that might be of interest:
https://forums.macrumors.com/threads/561251/
 

wolfenkraft

macrumors regular
Mar 6, 2008
105
0
I won't write the helper methods, but I would see a recursive solution looking something like this:

Code:
java.lang.String removeVowels(java.lang.String src) {
  if(src == null) return ""; //Base case/input validation
  if(src.length() == 0) return ""; //Base case
  if(src.length() == 1) { //Base case
    if (isVowel(src.charAt(0)) {
      return "";
    } else {
      return src;
    }
  }
  if(isVowel(src.charAt(0)) { //length > 1, recursive case
    return removeVowels(src.substring(1));
  } else {
    return src.charAt(0) + removeVowels(src.substring(1));
  }
}

That looks reasonable from a conceptual stand point. Rule 1 when dealing with recursion is set up your base cases. Everything that involves recursion and a list should start with a "is null?" and/or "is length==0?" that's pretty much universal regardless of language.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.