0

I was wondering if I could get some help on a proper way of appending consonants to a StringBuilder variable.

As it stands right now, it successfully finds and counts up the number of vowels found in a sentence, however, I'm having trouble creating a new variable that excludes them.

    char[] vowels = {'a', 'e', 'i', 'o', 'u'};
    int vowelCount = 0;
    String defParagraph = "This is an example sentence.";
    StringBuilder sbParagraph = new StringBuilder(defParagraph);
    StringBuilder vowParagraph = new StringBuilder("");

    System.out.print("Characters: " + sbParagraph.length());

    for (int i = 0; i < sbParagraph.length(); i++) {
        for (int j = 0; j < vowels.length; j++) {
            if (sbParagraph.toString().toLowerCase().charAt(i) == vowels[j]) {
                vowelCount++;
            }
        }
    }

I've tried simply adding a vowParagraph.append(sbParagraph.charAt(i) in the loop, but it gives me multiples of the same character in the new string. I've also given thought to copying the original StringBuilder variable and simply removing the characters but I simply don't know the best way to go about doing that.

I'm not sure if I should stick with two loops and an array, or if I should simply make a massive if/then condition to check for values. To be honest that seems like the easiest way, but also seems a bit too verbose and inefficient.

If anyone can help me shed light on my foolishness I'd appreciate it. This has been driving me nuts.

Mat
  • 202,337
  • 40
  • 393
  • 406
Battleroid
  • 861
  • 2
  • 14
  • 30

5 Answers5

2

Here is the alternate version,

String regex = "[aeiou]";
Matcher m = Pattern.compile(regex,Pattern.CASE_INSENSITIVE).matcher(defParagraph); 
while (m.find()) {
  vowelCount++;
}
String vowParagraph=defParagraph.replaceAll(regex, "").toLowerCase();  
Adisesha
  • 5,200
  • 1
  • 32
  • 43
1

You can change your loop like this to avoid multiples:

for (int i = 0; i < sbParagraph.length(); i++) {
    char c = defParagraph.toLowerCase().charAt(i);
    boolean isVowel = false;
    for (int j = 0; j < vowels.length; j++) {
        if (c == vowels[j]) {
            isVowel = true;
            break;
        }
    }
    if (isVowel) {
        vowelCount++;
    } else {
        vowParagraph.append(c);
    }
}
Keppil
  • 45,603
  • 8
  • 97
  • 119
1

You haven't stated what your result should be? Are you just wanting to count how many vowels are in the sentence? Or do you want a string at the end that represents unique vowels?

If you want a string at the end that has all the vowels from the sentence then do what you were thinking. Append the vowel in the for(int j... loop. The reason you are seeing multiples is because there are multiples in the sentence. (2 i's, 2 a's, 5 e's).

EDIT: I just noticed that your question states you "want help appending consonants to a StringBuilder". Why do you even care about vowels then?

EDIT 2: To append only the consonants to a Stringbuilder try this

    String defParagraph = "This is an example sentence.";
    StringBuilder sbParagraph = new StringBuilder(defParagraph);
    StringBuilder conPara = new StringBuilder();

    System.out.println("Characters: " + sbParagraph.length());

    for (int i = 0; i < sbParagraph.length(); i++) {
        char c = sbParagraph.toString().toLowerCase().charAt(i);
        if (c == 'a' || c=='e' || c=='i' || c=='o' || c=='u') {
            continue; // Skip this character.
        }
        conPara.append(c);
    }

    System.out.println("conPara: " + conPara);

Output is:

 Characters: 28
 conPara: ths s n xmpl sntnc.

Since this is homework I'll leave it for you to figure out how to remove the spaces. (They are neither vowels or consonants).

km1
  • 2,383
  • 1
  • 22
  • 27
1

How about avoid the O(N^2) loop?

Set<Character> vowels = new HashSet<Character>(Arrays.asList('a','e','i','o','u'));  
int vowelCount = 0;
String sbParagraph = "This is an example sentence.";
StringBuilder vowParagraph = new StringBuilder();

System.out.print("Characters: " + sbParagraph.length());

for (int i = 0, len = sbParagraph.length(); i < len; i++) {  
    int theChar = sbParagraph.charAt(i);
    if(vowels.contains(Character.toLowerCase(theChar)){    
        vowelCount++;    
     }  
     else{  
         vowParagraph.append(theChar);
      }  
}  
Cratylus
  • 52,998
  • 69
  • 209
  • 339
1

This is similar to a few of the other answers, but with some tweaks and explanations of why the changes from your code were made. On a side note though, if regular expressions are an option for you, take a look at Adi's answer. He gives you another way to approach the problem, but since this is homework not sure if it is a viable solution. Anyway, with explanations (skip to the bottom for the final product):

Changes to what you declare to start with

int vowelCount = 0;
// All the Strings/StringBuilders can be final since we will never reinstantiate them
final String defParagraph = "This is an example sentence.";
// We'll just make a lowercase version here. That way we don't 
// .toLowerCase() everytime though the loop, and for people that complain
// about trying to optimize - I think it's easier to read too.
final String lowerCaseVersion = defParagraph.toLowerCase();
// Declare the stringBuilder with the size of defParagraph. That is the
// maximum size the vowel-less text could be, and ensures the stringBuilder
// won't overflow it's initial capacity and have to waste time growing.
final StringBuilder newParagraph = new StringBuilder(defParagraph.length());
// Not using the vowel array. We will remove the loop 
// and just || them together - see below
//char[] vowels = {'a', 'e', 'i', 'o', 'u'};
// You didn't need sbParagraph for anything you had (defParagraph works fine).
// Also, you could have just been a regular String since you never changed it.
//StringBuilder sbParagraph = new StringBuilder(defParagraph);
// Don't need vowParagraph since we aren't tracking the actual vowels, just the count
//StringBuilder vowParagraph = new StringBuilder("");

Changes to the actual loop

 for (int i = 0; i < lowerCaseVersion.length(); i++) {
  // grab the current character
  char tempChar = lowerCaseVersion.charAt(i);
  if ('a' == tempChar || 'e' == tempChar || 'i' == tempChar 
        || 'o' == tempChar || 'u' == tempChar) {
    // It matched one of the vowels, so count it
    vowelCount ++;
  } else {
    // It didn't match a vowel, so add it the consonants stringBuilder
    // Oh, and append a character from the original, not the lowerCaseVersion
    newParagraph.append(defParagraph.charAt(i));
  }
}

And then all together without the comments:

int vowelCount = 0;
final String defParagraph = "This is an example sentence.";
final String lowerCaseVersion = defParagraph.toLowerCase();
final StringBuilder newParagraph = new StringBuilder(defParagraph.length());

System.out.println("Characters: " + defParagraph.length());

for (int i = 0; i < lowerCaseVersion.length(); i++) {
  char tempChar = lowerCaseVersion.charAt(i);
  if ('a' == tempChar || 'e' == tempChar || 'i' == tempChar 
        || 'o' == tempChar || 'u' == tempChar) {
    vowelCount ++;
  } else {
    newParagraph.append(defParagraph.charAt(i));
  }
}

System.out.println("\tVowel: " + vowelCount);
System.out.println("\tDefPara: " + defParagraph.toString());
System.out.println("\tNewPara: " + newParagraph.toString());

And the output looks like:

Characters: 28
  Vowels: 9
  DefPara: This is an example sentence.
  NewPara: Ths s n xmpl sntnc.

Notes

  1. Using final is really optional in this case. I tend to use it where I can, but it's probably a personal preference. This Question has some discussion on when to use final and might be worth checking out.
Community
  • 1
  • 1
Windle
  • 1,385
  • 2
  • 14
  • 33