简体   繁体   English

字符串中的字母计数。 C#

[英]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' ". “'Program.Alphabet是一种类型,在给定的上下文中无效”。

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<TKey,TValue>最适合这里,您可以按照以下方式在几行中完成:

 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: 这也是Linq的解决方案:

   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而不是enum来保存对( charint

        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: 使用LINQ的另一个Dictionary示例:

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. ToLower()会将整个字符串转换为小写字母-因此我们将'A'和'a'视为同一事物。

Where(c => Char.IsLetter(c)) will cause us to ignore any non-letter characters (for example "!"). Where(c => Char.IsLetter(c))将使我们忽略任何非字母字符(例如“!”)。

GroupBy(c => c) groups all the characters together. GroupBy(c => c)将所有字符分组在一起。 So if the string is "Moo" then two groups will be created. 因此,如果字符串为“ Moo”,则将创建两个组。 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. 一组中包含键“ m”,其中包含一个“ m”,另一组中包含键“ o”,其中包含两个“ o”。

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. 然后,我们将这些组转换为字典,在本示例中,该字典将单个字符(即“ o”)映射到数字(即出现的次数)即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). ToDictionary(k => k.Key, v => v.Count())从每个组创建一个键-值对,键是字符,值(数字)是该组中元素的数量(该字符的总数)。

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... 只需使用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... ...如果您不能使用.Count() ,则可以随时编写自己的...

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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