简体   繁体   中英

Letter count in a string. C#

I need to do this program that counts how much every letter of the alphabet occurs in a sentence (inputted by the user). I tried using enums for every letter and with every loop it check which letter it is, and increments accordingly. Yet I'm doing something wrong, I have some syntax errors in the loop:

" 'Program.Alphabet is a type, which is not valid in the given context' ".

What am I doing wrong? Is there a better way to fix it/ improve it. For this exercise we cannot use Arrays, or special count functions. Many thanks.

class Program
{

    enum Alphabet
    {

        a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0,
        h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0,
        o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0,
        v = 0, w = 0, x = 0, y = 0, z = 0

    }

    static void Main(string[] args)
    {
        Console.WriteLine("Enter here your sentence: ");
        string input = Console.ReadLine();

        for (int i = 0; i < input.Length; i++)
            {
            for (int x = 0; x < 25; i++)
                if (input[i] == Alphabet[x])
                {
                    Alphabet[x]++;
                }
            }
    }
}

Dictionary<TKey,TValue> is best suited here, you can do it in few lines following way:

 Dictionary<Char,int> alphabets = new Dictionary<Char,int>();

for (int i = 0; i < input.Length; i++)
{
    char character= input[i];
    if(Char.IsLetter(character)) // this is important user can enter numbers as well
    {
        if(alphabets.ContainsKey(character)) // if letter already in increment count
                alphabets[character] = alphabets[character] + 1;
        else
               alphabets.Add(character,1); // else add in dictionary 
    } 
}

Here is a Linq inpired solution as well:

   var result = input.Where(character => Char.IsLetter(character))
                     .GroupBy(alphabet=>alphabet)
                     .Select(alphabet=> new 
                                 {
                                   Letter = alphabet.Key,
                                   Count = alphabet.Count()
                                 });

You should use Dictionary , instead of enum , in order to save pair ( char , int )

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

        foreach (var c in input.ToLower())
        {
            if (!countDictionary.ContainsKey(c))
            {
                countDictionary.Add(c, 0);
            }

            countDictionary[c]++;
        }

EDIT: Sorry, just noticed:

For this exercise we cannot use Arrays, or special count functions. Many thanks.

In this case, it sounds like this solution might not be suitable for your problem? Either way, this sounds like a very peculiar exercise! Let me see if I can figure out the least worst way to achieve this without collections.

Another Dictionary example using LINQ:

Dictionary<char, int> characterCount = input.ToLower()
    .Where(c => Char.IsLetter(c))
    .GroupBy(c => c)
    .ToDictionary(k => k.Key, v => v.Count());

To break each call down:

ToLower() will convert the entire string into lower case - so we will count 'A' and 'a' as the same thing.

Where(c => Char.IsLetter(c)) will cause us to ignore any non-letter characters (for example "!").

GroupBy(c => c) groups all the characters together. So if the string is "Moo" then two groups will be created. One group with a key of 'm' and a single 'm' contained within it and a second group with a key of 'o' with two 'o's inside it.

We then convert these groups into a dictionary which, in this example, maps a single character ie 'o' to a number (the number of times it appeared) ie 2.

ToDictionary(k => k.Key, v => v.Count()) creates a key-value pair from each group, with the key being the character and the value (number) being the number of elements in that group (the total number of that character).

You just misused enums. I suggest you convert that enum to a simple array or dictionary and your code will work fine just like the code below :

var alphabets = new Dictionary<char, int>()
        {
            {'a', 0},{'b', 0},{'c', 0},{'d', 0},
            {'e', 0},{'f', 0}, {'g', 0},{'h', 0},
            {'i', 0},{'g', 0},{'k', 0}, {'l', 0},
            {'m', 0},{'m', 0},{'o', 0},{'p', 0},
            {'k', 0},{'r', 0},{'s', 0},{'t', 0},
            {'w', 0},{'x', 0}, {'y', 0},{'z', 0},
        };


        Console.WriteLine("Enter here your sentence: ");
        string input = Console.ReadLine();

        for (int i = 0; i < input.Length; i++)
        {
            if (alphabets.ContainsKey(char.ToLower(input[i])))
            {
                 alphabets[char.ToLower(input[i])]++;   
            }

        }

Just use LINQ...

var results = input.Where(c=>char.IsLetter(c))
                   .GroupBy(i => i)
                   .ToDictionary(k => k.Key, v => v.Count());

... if you can't use .Count() you could always write your own...

public static class Tools
{
    public static int MyCount(this IEnumerable set)
    {
        if (set == null)
            return 0;

        var enumerator = set.GetEnumerator();
        var cnt = 0;
        while (enumerator.MoveNext())
            cnt++;
        return cnt;
    }
}

... If you really want to annoy your teacher/classmates then do something like this ...

public static IDictionary<char, int> CountStuff(this string set)
{
    var results = new Dictionary<char, int>();
    if (set == null)
        goto bottom;

    var enumerator = set.GetEnumerator();
top:
    if (enumerator.MoveNext())
    {
        var v = (int)enumerator.Current;
        if (v < 97)
            v = v + 96;
        var c = (char)v;

        if (v < 97 || v > 122)
            goto top;

        if (results.ContainsKey(c))
            results[c]++;
        else
            results.Add(c, 1);

        goto top;
    }

bottom:
    return results;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM