views:

1025

answers:

6

I'm new to C#. While learning it, I tried to design a program which count the vowels in a sentence.

In my code, I used the "foreach" statement with the if-else if statement. I would like to convert these line of code using the switch statement but I'm not really sure where to go. Do I need to add a new method? I would appreciate your help.

This is what I tried so far: I checked this one is very wrong. The "case 1" for example needs to have a constant. I'm not sure what constant shall I use here.

foreach (char v in yourSentence)
{
    switch (v)
    {
    case 1: 
        (v==ch1); 
      counta++; 
     j++; 
     break;

    case 2: 
     (v==ch2); 
     counte++; 
     j++; 
     break;
    case 3: 
     (v==ch3); 
     counti++; 
     j++; 
     break;
    case 4: 
     (v==ch4); 
     counto++; 
     j++; 
     break;
    case 5: 
     (v==ch3); 
     counti++; 
     j++; 
     break;             
    }
}

Another question: I tried to change the color of the display text in the listBox. Is that possible to have different colors? What I also tried here is the first 5 (listBox1.Items.Add) are violet. And the sum of the (listBox1.Items.Add) is blue. But it seems that it didn't change. Did I miss something here?

private void btnCount_Click(object sender, EventArgs e)
{
    string yourSentence;
    yourSentence = textBoxVowels.Text.ToLower().Trim();

    char ch1 = 'a';
    char ch2 = 'e';
    char ch3 = 'i';
    char ch4 = 'o';
    char ch5 = 'u';

    int counta = 0;
    int counte = 0;
    int counti = 0;
    int counto = 0;
    int countu = 0;

    int j = counta + counte + counti + counto + countu;



    foreach (char v in yourSentence)
    {
        if (v == ch1) { counta++; j++; }

        else if (v == ch2) { counte++; j++; }

        else if (v == ch3) { counti++; j++; }

        else if (v == ch4) { counto++; j++; }

        else if (v == ch5) { countu++; j++; }
    }

    listBox1.Items.Add("There are " + counta.ToString().Trim() + " a's in the sentence");
    listBox1.Items.Add("There are " + counte.ToString().Trim() + " e's in the sentence");
    listBox1.Items.Add("There are " + counti.ToString().Trim() + " i's in the sentence");
    listBox1.Items.Add("There are " + counto.ToString().Trim() + " o's in the sentence");
    listBox1.Items.Add("There are " + countu.ToString().Trim() + " u's in the sentence");
    listBox1.Font = new Font("Arial", 12, FontStyle.Bold);
    listBox1.ForeColor = Color.Violet;

    listBox1.Items.Add("There are " + j.ToString().Trim() + " vowels in the sentence");
    listBox1.ForeColor = Color.Blue;
}


private void btnClear_Click(object sender, EventArgs e)
{
    textBoxVowels.Text = null;
    listBox1.Items.Clear();
}

====

@Noldorin: I tried the code you gave and it seems it didn't work. did I miss something here:

  public static int CountVowels(string value)
    {
        char ch1 = 'a';
        char ch2 = 'e';
        char ch3 = 'i';
        char ch4 = 'o';
        char ch5 = 'u';

        int counta = 0;
        int counte = 0;
        int counti = 0;
        int counto = 0;
        int countu = 0;


        const string vowels = "aeiou";
        return value.Count(chr => vowels.Contains(char.ToLower(chr)));
        int j = counta + counte + counti + counto + countu;

        //listBox1.Items.Add("There are " + j.ToString().Trim() + " vowels in the sentence");
    }

==========

The switch statement is working fine now. Thanks for the hint. Now I recalled that I have to use a constant value.

Thanks to dahlbyk. Maybe I'll try it and see if it works.

Does anybody have any idea what event I'll use if I want to display the number of vowels while writing?

Thanks again

+6  A: 

Or just simplify the whole problem by using a bit of LINQ. :)

public static int CountVowels(this string value)
{
    const string vowels = "aeiou";
    return value.Count(chr => vowels.Contains(char.ToLower(chr)));
}

The Count extension method is particularly well suited to this task. Also, notice the use of a string of all vowels to check each character - much simpler than a switch statement.

Note: It seems I missed the fact that you want to count each vowel individually. In this case, the LINQ becomes a bit more complicated (at least if you want to do it efficiently), but I shall leave that as an exercise for you. Regardless, a switch statement is probably a good way to learn the basics of C#.


Since you're probably curious about the switch statement anyway, the following code uses the correct syntax:

foreach (var chr in sentence)
{
    switch (chr) 
    {
        case 'a':
            ...
            break;
        case 'e':
            ...
            break;
        case 'i':
            ...
            break;
        case 'o':
            ...
        case 'u':
            ...
            break;
     }
}
Noldorin
if I simplify it like your given example, which one do I still include in my code?
tintincute
First part is OK, but will only give the total number of vowels (and is probably not suited to learn the language). Second part is wrong: case needs a constant.
M4N
@Martin: which part do you mean? You mean my code above? Or the one which uses the LINQ?
tintincute
@Noldorin: thanks for the advice. I tried the first code you gave and I'm getting an error. Which part of my code will I retain? thanks
tintincute
If you're not using .NET 3.5, the extension method I gave won't work. I recommend you just try and get the switch statement working well first.
Noldorin
@Noldorin: Yes I'm using it. The switch statement already works
tintincute
@tintincute: Well for the extension method, you'll need to define it and use it in a certain way. It's quite simple though. See the MSDN page on the subject: http://msdn.microsoft.com/en-us/library/bb383977.aspx
Noldorin
Adding more vowels to the constant will support some other european languages :const string vowels = "aáàeéèiíìóòouúù";
Lluis Martinez
+4  A: 

I think you misunderstood how 'switch/case' works. Just change them to this:

case 'a': 
     counta++; 
     j++; 
     break;

Case needs a constant value that should be compared to the current character.

M4N
@Martin: this works fine. Thanks for the input:-)
tintincute
+2  A: 

Please also check the other answers to your questions for many helpful tips. I'm just rewriting your first piece of example code from your question to probably let it do what you mean:

foreach (char v in yourSentence)
{
    switch (v)
    {
        case 'a': counta++; j++; break;
        case 'e': counte++; j++; break;
        case 'i': counti++; j++; break;
        case 'o': counto++; j++; break;
        case 'u': countu++; j++; break;
    }
}

You seem to want to increase one of the { counta, counte, counti, counto, countu } variables for the five specific vowels using the switch (right?) and also increase the j variable for each of the vowels.

Having given this answer, I would personally do something different altogether. Like the LINQ example given by Noldorin. Or something like this, as perhaps suggested by cherryalpha:

// create dictionary
var counts = new Dictionary<char,int>();

// initialize it for the vowels
foreach (char v in "aeiuo")
{
    counts.Add(v, 0);
}

// count all characters in sentence
foreach (char v in yourSentence) {
    if ( counts.ContainsKey(v) ) {
        // increase count for known characters
        counts[v]++;                        
    } else {
        // add new count for characters not seen previously
        counts.Add(v,1);
    }
}

// calculate your total number of vowels
j = counts['a'] + counts['e'] + counts['i'] + counts['o'] + counts['u'];

Quick warning, just in case: You would need a using System.Collection.Generic at the top of your source file that contains this code to make sure the generic Dictionary is known by its short name.

(And be aware that this code will not only give you vowel counts, but counts for all the other characters in yourSentence as well.)

peSHIr
@peSHIr: the code of Noldorin I can't have it work. I think I miss something. I'm not familiar with this one but I would love to try it out.
tintincute
@tintincute: Make sure you are using .NET Framework 3.5 and include a "using System.LINQ" at the top of your source file, or the LINQ suggestion will never work.
peSHIr
@peSHIr: yes I'm using it: I can see at the top of my source file:using System.Collections.Generic;using System.Drawing;using System.Linq;
tintincute
+3  A: 

Here's a more advanced solution:

public static Dictionary<char, int> CountLetters(string value, string letters)
{
    var counts = letters.ToDictionary(c => c.ToString(), c => 0, StringComparer.OrdinalIgnoreCase);

    var groups = from c in value
                 let s = c.ToString()
                 where counts.ContainsKey(s)
                 group s by s;

    foreach(var g in groups)
        counts[g.Key] = g.Count();

    return counts;
}

Which you could use like this:

var letterCounts = CountLetters(yourSentence, "aeiou");

int countA = letterCounts["a"];
int countE = letterCounts["e"];
int countI = letterCounts["i"];
int countO = letterCounts["o"];
int countU = letterCounts["u"];

int total = countA + countE + countI + countO + countU;

Update: Just realized that a StringComparer won't work for char keys. Switching to string key - not as efficient as char, but easier than writing a case-insensitive char comparer. I prefer the comparer approach to doing some sort of ToLower/ToUpper on everything dictionary-related.

dahlbyk
@dahlbyk: In your code are you using an array here?
tintincute
He's using a Dictionary (aka map, aka associative array) - http://en.wikipedia.org/wiki/Associative_array
Pavel Minaev
@Pavel Minaev: Do you think I can also use array here in my code? Thanks for the link
tintincute
An array can only be indexed with a positional integer. The benefit of using a dictionary is that you can efficiently access elements using an arbitrary* key (like a char or string). There are certainly solutions using arrays, but the general consensus here seems to favor a dictionary approach. (* arbitrary within some important constraints)
dahlbyk
@dahlbyk: I'll try this and see if it works. Thanks for the input.I'm looking now how to have the event works
tintincute
A: 

I wrote a method that returns a Dictionary:

    public Dictionary<char,int> CountVowels(string sentance)
    {
        const string vowels = "aeiou";

        Dictionary<char,int> dic = new Dictionary<char, int>();

        foreach (char c in vowels)
            dic.Add(c, sentance.Count(chr => c == chr));

        return dic;
    }
CD
+1  A: 
const string VOWELS = "aeiou";
var str = "Lorem ipsum dolor sit amet";
var q = from ch in str
        where VOWELS.Contains(ch)
        group ch by ch into g
        select g;
var dict = q.ToDictionary(_ => _.Key, _ => _.Count());
Lloyd
i'm sorry but i don't understand this coding.that means i still have a lot to learn. but thanks for sharing anyway,
tintincute
THis code is LINQ, which makes life a whole lot easier. It is in the .NET Framework 3.5 release. (visual studio 2008). It allows you to query arbitrary collections of objects (and a string is a 'collection' of characters), or xml, or sql, etc.
Colin
@Colin: I think it is. But it's quite to understand haven't learned yet the data type "var" -(variable). not really sure how it works but I'd love to look at it a reference later.
tintincute