4

At the end of my loop, I am planning on displaying the number of consonants and vowels in the sentence. I was wondering if there was a more efficient way to check how many consonants and vowels are in a given sentence, rather than using an if statement and manually inputting every letter. (key refers to my Scanner which has already been initialized)

Edit: It needs to ignore digits and other special characters, so for example if I write Hello@ how 1are you?. There should be 8 vowels and 6 consonants.

System.out.println("Please enter the sentence to analyze: ");

String words = key.nextLine(); //the sentence the user inputs
int c = 0; //# of consonants
int v = 0; //# of vowels
int length = words.length(); //length of sentence
int check; //goes over each letter in our sentence

for(check = 0; check < length; check++){
char a = words.charAt(check);   

        if(a == 'a' || a == 'A' || a == 'e' || a == 'E' || a == 'i' || a == 'I' || a == 'o'
            || a == 'O' || a == 'u' || a == 'U' || a == 'y' || a == 'Y')
            v = v + 1;
        else if(a == 'b' || a == 'B' || a == 'c' || a == 'C' || a == 'd' || a == 'D' || a == 'f'
            || a == 'F' || a == 'g' || a == 'G' || a == 'h' || a == 'H' || a == 'j' || a == 'J' 
            || a == 'k' || a == 'K' || a == 'l' || a == 'L' || a == 'm' || a == 'M' || a == 'n' 
            || a == 'N' || a == 'p' || a == 'P' || a == 'q' || a == 'Q' || a == 'r' || a == 'r'
            || a == 's' || a == 'S' || a == 't' || a == 'T' || a == 'v' || a == 'V' || a == 'w'
            || a == 'W' || a == 'x' || a == 'X' || a == 'z' || a == 'Z')
                c = c + 1;
}
t3rrh42d2
  • 134
  • 1
  • 2
  • 10
  • First thing: get rid of that ugly `else if`. First use `String#replaceAll()` to get rid of everything that isn't a letter. If a letter's not a vowel, it has to be a consonant, right? – awksp Jun 04 '14 at 22:53
  • 1
    @user3580294 not if it is a digit or another kind of character. – Luiggi Mendoza Jun 04 '14 at 22:53
  • You could downcase and use a character class regex, if nothing else, although it'd be nice to wrap those operations up in utility methods. – Dave Newton Jun 04 '14 at 22:53
  • Does aa count as 2 vowels or just one? – David Brossard Jun 04 '14 at 22:53
  • http://stackoverflow.com/questions/19661199 – AntonH Jun 04 '14 at 22:53
  • @LuiggiMendoza Well, I did say "letter", not "character"... – awksp Jun 04 '14 at 22:54
  • 1
    Technically he did say if a *letter* isn't a vowel... – Dave Newton Jun 04 '14 at 22:54
  • @Kon Yes. A *letter* is either a vowel or consonant (in English, at least). – awksp Jun 04 '14 at 22:55
  • 1
    Is y a consonant or vowel? It depends on the language... – David Brossard Jun 04 '14 at 22:55
  • @user3580294 But counting only vowels and leaving the rest to be consonants would lead to the opposite of what you want exactly because you said "letter", not "character" :P – Doodad Jun 04 '14 at 22:58
  • @Doodad What do you mean by "opposite of what you want"? – awksp Jun 04 '14 at 22:59
  • you can use regexp to match what you want. For example if you want vowells you can use [aeiouAEIOU] – Federico Piazza Jun 04 '14 at 22:59
  • I'm sorry, I wasn't very clear. I meant that if you take off vowels and consider everything else consonants, you would get more than just letters being counted. Spaces would be counted as consonants, for example. And exactly because you said "letter", not "character", that wouldn't be what you want, because spaces are not letters. – Doodad Jun 04 '14 at 23:00
  • AntonH, if I am not mistaken, the link you sent me will have any non-vowel raise the consonant counter, which is what I am trying to avoid, like Luigi said – t3rrh42d2 Jun 04 '14 at 23:00
  • @Doodad I did say to use `replaceAll()` to remove everything that isn't a letter... – awksp Jun 04 '14 at 23:02
  • @user3580294 Pardon me, my friend, but that's very true, my mistake. – Doodad Jun 04 '14 at 23:05

10 Answers10

5

Use Character.isLetter(ch) to determine if the character is a vowel or a consonant, then check to see if the character in question is in the set of vowels.

One way to create the set of vowels:

    Set<Character> vowels = new HashSet<Character>();
    for (char ch : "aeiou".toCharArray()) {
        vowels.add(ch);
    }

And to increment v or c:

    if (Character.isLetter(a)) {
        if (vowels.contains(Character.toLowerCase(a))) {
            v++;
        } else {
            c++;
        }
    }
3

Assuming you already have a letter (vowel or consonant, not a digit nor a symbol or anything else), then you can easily create a method to define if the letter is a vowel:

static final char[] vowels = { 'a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U', 'y', 'Y' };

public static boolean isVowel(char c) {
    for (char vowel : vowels) {
        if (c == vowel) {
            return true;
        }
    }
    return false;
}

public static boolean isConsonant(char c) {
    return !isVowel(c);
}

Note that I set Y and y as vowels since seems that they are in your language. In Spanish and English, Y is a consonant (AFAIK).

You can easily check if the char is a letter or not using Character#isLetter.

So, your code would become into:

for(check = 0; check < length; check++){
    char a = words.charAt(check);
    if (Character.isLetter(a)) {
        if (isVowel(a)) {
            v++;
        } else {
            c++;
        }
    }
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
2

How about something like

String vowels = "aeiouyAEIOUY"; // you can declare it somewhere before loop to 
                                // to avoid redeclaring it each time in loop

//inside loop
if ((a>='a' && a<='z') || (a>='A' && a<='Z')){ //is letter
    if (vowels.indexOf(a)!=-1)                 //is vowel
        v++;
    else                                       //is consonant
        c++;
}
Pshemo
  • 122,468
  • 25
  • 185
  • 269
2

I am sure this can be improved upon, but I'll throw it in the ring anyways. Remove non-characters from the sentence, lowercase it, then convert to a char array and compare it to a char array of vowels that are all lowercase.

String myText = "This is a sentence.";

    int v = 0;

    char[] vowels = {'a','e','i','o','u'};
    char[] sentence = myText.replaceAll("[^a-zA-Z]","").toLowerCase().toCharArray();

    for (char letter : sentence) {
        for (char vowel : vowels) {
            if (letter == vowel) {
                v++;
            }
        }
    }
    System.out.println("Vowels:"+ v);
    System.out.println("Consonants:" + (sentence.length -v));
1

You can do a range check to make sure it is a letter, then check if it one of the vowels:

if( ( a >= 'a' && a<= 'z' ) || ( a >= 'A' && a <= 'Z' ) )
{
    // is letter
    switch( a )
    {
        case 'a': case 'A':
        case 'e': case 'E':
        case 'i': case 'I':
        case 'o': case 'O':
        case 'U': case 'u':
             ++v;
             break;
        default: // don't list the rest of the characters since we did the check in the if statement above.
             ++c;
    }
}
awksp
  • 11,764
  • 4
  • 37
  • 44
clcto
  • 9,530
  • 20
  • 42
1

One easy way would be to create 2 lists:

  • one contains vowels (a, e, i, o, u)
  • the other contains consonants

Then you iterate over each character in the Java string.

See a sample below:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Counter {
    public static void main(String[] args) {
        String test = "the fox is in the woods";
                    test = test.toLowerCase();
        List<Character> vowels = new ArrayList<Character>();
        vowels.addAll(Arrays.asList(new Character[]{'a', 'e', 'i', 'o', 'u'}));
        List<Character> consonants = new ArrayList<Character>();
        consonants.addAll(Arrays.asList(new Character[]{'b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'}));
        int vcount = 0;
        int ccount = 0;
        for (int i = 0; i < test.length(); i++){
            Character letter = test.charAt(i);
            if (vowels.contains(letter)){
                vcount ++;
            } else if (consonants.contains(letter)){
                ccount++;
            }
        }

        System.out.println(vcount);
        System.out.println(ccount);
    }
}
David Brossard
  • 13,584
  • 6
  • 55
  • 88
1

Oh, there's certainly a much more readable way to do it. Not sure if that meets the "better" definition.

As a start, I'd suggest that you encapsulate what you have into methods that you can write once and call anywhere:

package misc;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ParseUtils get counts of vowels and consonants in sentence
 * @author Michael
 * @link https://stackoverflow.com/questions/24048907/how-can-i-check-how-many-consonants-and-vowels-there-are-in-a-sentence-in-java
 * @since 6/4/2014 6:57 PM
 */
public class ParseUtils {

    private static final String VOWEL_PATTERN_STR = "(?i)[aeiou]";
    private static final Pattern VOWEL_PATTERN = Pattern.compile(VOWEL_PATTERN_STR);
    private static final String CONSONANT_PATTERN_STR = "(?i)[b-df-hj-np-tv-z]";
    private static final Pattern CONSONANT_PATTERN = Pattern.compile(CONSONANT_PATTERN_STR);

    private ParseUtils() {}

    public static void main(String[] args) {
        for (String arg : args) {
            System.out.println(String.format("sentence: '%s' # letters: %d # vowels: %d # consonants %d", arg, arg.length(), getNumVowels(arg), getNumConsonants(arg)));
        }
    }

    public static int getNumVowels(String sentence) {
        return getMatchCount(sentence, VOWEL_PATTERN);
    }

    public static int getNumConsonants(String sentence) {
        return getMatchCount(sentence, CONSONANT_PATTERN);
    }

    private static int getMatchCount(String s, Pattern p) {
        int numMatches = 0;
        if ((p != null) && (s != null) && (s.trim().length() > 0)) {
            Matcher m = p.matcher(s);
            while (m.find()) {
                ++numMatches;
            }
        }
        return numMatches;
    }

}
duffymo
  • 305,152
  • 44
  • 369
  • 561
  • I'm pretty sure for `VOWEL_PATTERN_STR` you don't need `|` in a character class. `(?i)[aeiou]` by itself shoudl work. – awksp Jun 04 '14 at 23:23
  • True enough - going too fast. I'll edit. Don't see why that's worth a downvote. – duffymo Jun 05 '14 at 09:28
0

Split the String by whitespaces and and Calculate only the number of Vowels. Then Number of consonants = Length of Sentence - No. of Vowels.

Detailed Code:

System.out.println("Please enter the sentence to analyze: ");
int v = 0;
int c = 0;
String string = key.nextLine(); //the sentence the user inputs
String[] stringArray = string.split(" ");
for(int i=0;i<stringArray.length;i++)
  {
     for(int j= 0; j<string.length(); j++)
      {
      char a = string.charAt(j);   

    if(a == 'a' || a == 'A' || a == 'e' || a == 'E' || a == 'i' || a == 'I' || a == 'o'
        || a == 'O' || a == 'u' || a == 'U' || a == 'y' || a == 'Y')
        v = v + 1;
      }
        c= c+(stringArray.length)-v;
  }

System.out.println("Vowels:"+v+"  and Consonants:"+c);
Vamsee
  • 183
  • 1
  • 8
  • Wrong - there can be whitespace, numbers, special characters. – duffymo Jun 04 '14 at 23:14
  • Well, nobody enters a phone number to analyze the number of vowels and consonants and moreover those errors could be eliminated by proper Validations... @duffymo – Vamsee Jun 04 '14 at 23:23
  • The OP asked about a sentence. I think all those characters are fair game. This isn't a phone number. – duffymo Jun 05 '14 at 19:20
0

One way to do it is to get rid of the non-letters, then vowels and consonants, and get the length of what is left:

public class CountChars {
    public static final String CONSONANTS = "[BCDFGHJKLMNPQRSTVWXYZ]";
    public static final String VOWELS = "[AEIOU]"; // considering Y a consonant here
    public static final String NOT_LETTERS = "[\\W_0-9]";

    public static void main(String[] args) {
        String words = "How can I check how many consonants and vowels there are in a sentence in Java?";

        String letters = words.toUpperCase().replaceAll(NOT_LETTERS, "");
        System.out.println("Letters: " + letters.length());

        String vowels = letters.replaceAll(CONSONANTS, "");
        System.out.println("Vowels: " + vowels.length());

        String consonants = letters.replaceAll(VOWELS, "");
        System.out.println("Consonants: " + consonants.length());
    }
}
helderdarocha
  • 23,209
  • 4
  • 50
  • 65
0

Here is the best way of doing this:

public static void checkVowelsAndConsonants(String s){
    System.out.println("Vowel Count: " + (s.length() - s.toLowerCase().replaceAll("a|e|i|o|u|", "").length()));
    //Also eliminating spaces, if any for the consonant count
    System.out.println("Consonant Count: " + (s.toLowerCase().replaceAll("a|e|i|o| |u", "").length()));
}
Leigh
  • 28,765
  • 10
  • 55
  • 103
Actiwitty
  • 1,232
  • 2
  • 12
  • 20