-1

I can't figure out how to have both vowels and consonants. The vowels part of the code works fine. I have no idea how to add the consonants.

import java.util.Scanner;

public class Main
{
   public static void main(String args[])
   {
      Scanner in = new Scanner(System.in);

      System.out.println("Enter some text: ");
      String str = in.nextLine();
      System.out.println(str);

System.out.print("your input has " + count_Vowels(str) + "vowels");
    }
 public static int count_Vowels(String str)
    {
        int vcount = 0;
        for (int i = 0; i < str.length(); i++)
        {
            char ch = str.charAt(i);
            if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
            {
              vcount++;
            }
        }
        return vcount;
    }
public static int count_Consanants(String str)
    {
      int ccount = 0;
      for (int i = 0; i < str.length(); i++)
    {
      char ch = str.charAt(i);
      if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
      {
        vcount++;
      }
      else
      {
        consonants++;
      }
    }
  }  
}

I cannot seem to figure out the consonant part of the code

  • 2
    Isn't your code already doing what you want? If it's not a vowel, it's a consonant, so the else block of your if... else is incrementing the consonant counter. – MarsAtomic May 30 '20 at 21:53
  • 1
    Define a consonant: a character between 'a' and 'z that is not a vowel. – NormR May 30 '20 at 21:56

3 Answers3

1

Your code will also count other characters that are not consonants. Here is a simple way to count vowels and consonants:

for (int i = 0; i < str.length(); i++) {    
    //Checks whether a character is a vowel
    if (str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i' || str.charAt(i) == 'o' || str.charAt(i) == 'u') {      
        vCount++;    
    }    
    //Checks whether a character is a consonant    
    else if (str.charAt(i) >= 'a' && str.charAt(i)<='z') {        
        cCount++;    
    }    
}    

Similarly, you can also modify the code for upper case characters.


Slightly elegant:

Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u'));

for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);
    if (vowels.contains(c)) {
        vCount++;
    } else if (c >= 'a' && c <= 'z') {
        cCount++;
    }
}
Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43
0

Here is one way to do it.

  • First it converts the string to lower case to facilitate the search
  • Then it sets a string to the vowels. You may want to add y if you're counting that
  • The main part loops thru the array, ensuring the character is a letter, and then tallying the counts. It is important to only check letters since spaces and punctuation marks could throw off the results.
Scanner in = new Scanner(System.in);

System.out.println("Enter some text: ");
String str = in.nextLine().toLowerCase();
String vowels = "aeiou";
System.out.println(str);

int vcount = 0;
int ccount = 0;

for (char c : str.toCharArray()) {
    if (Character.isLetter(c)) {
        if (vowels.indexOf(c) >= 0) {
            vcount++;
        } else {
            // must be a consonant
            ccount++;
        }
    }
}
System.out.printf("There were %d vowels and %d consonants%n",
        vcount, ccount);

WJS
  • 36,363
  • 4
  • 24
  • 39
0

Process of elimination

You said:

i am stumped on the consonants

The basic idea is that after you have tested for the character being (a) of the Latin-script, (b) being a letter (not a digit, punctuation, etc.), and (c) not a vowel, you can assume you have a consonant.

As you can see at the center of the code example below, we examine each character with a cascading if statement, summarized here as pseudo-code:

        if( … not part of the Latin script, such as Korean or emoji )
        {
            other++;
        }
        else if( … not a letter, such as digit or punctuation )
        {
            other++;
        } 
        else if ( … definitely a vowel )
        {  
            vowel++;
        } 
        else if ( … maybe a vowel (`y`) )
        {  
            maybeVowel++;
        } 
        else  // Else definitely not a vowel, so it must be a consonant. 
        {  
            consonant++;
        }

char is legacy

The first two Answers are basically right, but use the obsolete char type. That type handles less than half of the over 140,000 characters defined in Unicode. And those Answers assume only English without diacriticals and such.

Unicode code point

Instead, make a habit of using code point integer numbers instead.

String input = " Face with Medical Mask" ;

Make a stream of the code point numbers for each character in the text.

IntStream intStream = input.codePoints() ;

Materialize an array from the stream.

int[] codePoints = intStream.toArray();

Loop each code point.

for ( int codePoint : codePoints )
{
    …
}

First see if the character is within the Latin script defined in Unicode. See Identify if a Unicode code point represents a character from a certain script such as the Latin script?.

if ( Character.UnicodeScript.LATIN.equals( Character.UnicodeScript.of( codePoint ) ) ) { … } else { other ++ ; ) 

Next we must test if this character is a letter or not.

 if ( Character.isLetter( codePoint ) ) { … } else { other ++ ; )  

To simplify our comparisons, we should convert to lowercase.

int lowercaseCodePoint = Character.toLowerCase( codePoint );

Next test for vowels. I do not know that Java or Unicode provides a test for vowel versus consonant. So we must define a set of vowels ourselves. I do not know about all Latin-based languages, but I can at least cover English vowels. Of course, y is tricky, so I will count that as in a maybeVowel count.

int[] vowelCodePoints = "aeiou".codePoints().toArray();
int[] maybeVowelCodePoints = "y".codePoints().toArray();

We will want to see if those arrays contain each character's code point number. So sort the arrays to enable a binary search.

Arrays.sort( vowelCodePoints );
Arrays.sort( maybeVowelCodePoints );

Add a test for vowel.

 if ( Arrays.binarySearch( vowelCodePoints , lowercaseCodePoint ) >= 0 )

Add a test for maybe vowel.

else if ( Arrays.binarySearch( maybeVowelCodePoints , lowercaseCodePoint ) >= 0 )

And if we get past both those vowel-related tests, we can assume our non-vowel lowercase Latin-script character is a consonant.

Put all the code together.

String input = " Face with Medical Mask";

IntStream intStream = input.codePoints();

int[] codePoints = intStream.toArray();
int[] vowelCodePoints = "aeiou".codePoints().toArray();
int[] maybeVowelCodePoints = "y".codePoints().toArray();

// Sort those arrays to enable binary search.
Arrays.sort( vowelCodePoints );
Arrays.sort( maybeVowelCodePoints );

int vowel = 0;
int maybeVowel = 0;
int consonant = 0;
int other = 0;
for ( int codePoint : codePoints )
{
    if ( Character.UnicodeScript.LATIN.equals( Character.UnicodeScript.of( codePoint ) ) )
    {
        if ( Character.isLetter( codePoint ) )
        {
            int lowercaseCodePoint = Character.toLowerCase( codePoint );
            if ( Arrays.binarySearch( vowelCodePoints , lowercaseCodePoint ) >= 0 )
            {  // If definitely a vowel…
                vowel++;
            } else if ( Arrays.binarySearch( maybeVowelCodePoints , lowercaseCodePoint ) >= 0 )
            {  // Else if maybe a vowel…
                maybeVowel++;
            } else
            {  // Else this non-vowel lowercase letter from Latin-script must be a consonant.
                consonant++;
            }
        } else { other++; }  // Else not a letter.
    } else { other++; }      // Else not in Latin script.
}

Dump to console.

// Report
System.out.println( "RESULTS  ----------------------------------------------" );
System.out.println( "input = " + input );
System.out.println( "codePoints = " + Arrays.toString( codePoints ) );
System.out.println( "Count code points: " + codePoints.length );
System.out.println( "vowelCodePoints = " + Arrays.toString( vowelCodePoints ) );
System.out.println( "maybeVowelCodePoints = " + Arrays.toString( maybeVowelCodePoints ) );
System.out.println( "vowel = " + vowel );
System.out.println( "maybeVowel = " + maybeVowel );
System.out.println( "consonant = " + consonant );
System.out.println( "other = " + other );
System.out.println( "vowel + maybeVowel+consonant+other = " + ( vowel + maybeVowel + consonant + other ) );
System.out.println( "END  ----------------------------------------------" );

Example usage

When run.

RESULTS  ----------------------------------------------
input =  Face with Medical Mask
codePoints = [128567, 32, 70, 97, 99, 101, 32, 119, 105, 116, 104, 32, 77, 101, 100, 105, 99, 97, 108, 32, 77, 97, 115, 107]
Count code points: 24
vowelCodePoints = [97, 101, 105, 111, 117]
maybeVowelCodePoints = [121]
vowel = 7
maybeVowel = 0
consonant = 12
other = 5
vowel + maybeVowel+consonant+other = 24
END  ----------------------------------------------

Tip: Read the humorous article, The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • I'm tempted to downvote this. The mouse-over-text of the downvote button says: "This answer is not useful". And this answer is definitely not useful for someone who obviously didn't yet wrap his head around ASCII, variables and loops. Here, the answer just looks like "showing off", and it would better be suited for a *real* question about the topic of unicode and such, and not as an answer to a question that should be closed as "unclear/looking for debugging help"... – Marco13 May 31 '20 at 00:03
  • @Marco13 The `char` type, as I said, really is flawed and obsolete. Working with code point integers is the correct way to handle characters in modern Java. I wrote this code using arrays rather than collections to keep the code simple and close to the code as seen in the Question. Teaching new programmers to expect only American English and ASCII text is irresponsible in the modern world of information systems. I wrote exactly the Answer I would have wanted to find if I were new to programming and writing that Question. What you call "showing off" I call showing basic text handling. – Basil Bourque May 31 '20 at 03:10
  • @Marco13 Your comment did inspire me to add pseudo-code up top to summarize the approach of determining a consonant by eliminating all other possibilities. Thanks for that. – Basil Bourque May 31 '20 at 03:19
  • There's no need to argue about the *contents* of the answer per se. In fact, I learned a bit from it (despite >20 years of programming experience). The point is: The asker posted a """question""" that boiled down to a code snippet that didn't compile due to undeclared variables. (No matter how low you set the bar: Someone will do the limbo). Your answer might have been a better fit for https://stackoverflow.com/questions/2533097 or similar ones. (Specifically: It would be pity if all your effort was wasted when this Q is deleted, as it should be) – Marco13 May 31 '20 at 12:21
  • (Corollary: I'd certainly **up**-vote the answer if it was posted to a question where it fits - e.g. the one that I linked to, but there may be even others where it fits better) – Marco13 May 31 '20 at 12:23