迭代字符串并计算出现次数

时间:2014-07-13 18:54:13

标签: c#

这就是问题:

  • 编写一个从控制台读取字符串的程序,并按字母顺序打印输入字符串中的所有字母以及字符串中每个字母出现的次数。

起初看起来很有趣并且不太复杂,但我无法解决它。

public static void Letters()
{
        string input;
        Console.Write("Enter a string:  ");
        input = Console.ReadLine();

        var chars = new List<char>();

        //To populate characters with the letters of the input but without repetition
        for(int index = 0; index < input.Length; index++)
        {
            if(!characters.Contains(input[index]))
                characters.Add(input[index]);
        }

        //To increment the counter corresponding to the character index
        int[] counter = new int[characters.Count];


        //Now what ?!

    }

我的想法是:

我创建了一个集合来保存输入字符串的字母,没有任何重复。

然后我使用相同大小的int数组,使每个int保存输入字符串中相应字母的出现次数。

我不仅不知道如何实现这一点,而且我感觉它不是一个理想的解决方案 问题。可能有一个查询或lambda表达式可以使这很容易 实施和阅读。

注意:此后的问题具有相同的性质。它的不同之处在于它要求 用一个“aaabbbcc”替换重复的字母到“abc”。

如果描述逻辑,我将不胜感激。我会尝试自己实现它, 只是指出我的逻辑。

编辑:

这是我使用字典的答案

public static void Letters()
{
        string input;
        Console.Write("Enter a string:  ");
        input = Console.ReadLine();

        var dict = new Dictionary<char, int>();

        for(int index = 0; index < input.Length; index++)
        {
            char theKey = input[index]; //just for clarity

            if(!dict.ContainsKey(theKey))
                dict.Add(theKey, 1);
            else
                dict[input[index]]++;
        }

        foreach(var key in dict.Keys)
        {
            Console.WriteLine("{0}\t{1}", key, dict[key]);
        }

4 个答案:

答案 0 :(得分:2)

Dictionnary<String, int>

Key = string =字母IE a,b,c,d,e,f ..... Int是出现次数

首先这样做:

Dictionnary.add(a,0)
...
Dictionnary.add(z,0);

然后读取字符串并执行此操作

Dictionnary[letterFound ] += 1;

有一种更好的方法可以了解每个字母的ASCi在初始化词典时的价值,但我不认为这种行为是强制性的。

祝你好运

答案 1 :(得分:2)

var myString = "Hello";

var dict = new Dictionary<char, int>();

foreach(var c in myString)
{
    if(!dict.ContainsKey(c))
        dict.Add(c, 1);
    else
        dict[c]++;
}

var orderedDict = dict.OrderBy(x => x.Key);

foreach(var kvp in orderedDict)
{
    Console.WriteLine("Letter: {0}, Times: {1}", kvp.Key, kvp.Value);
}

答案 2 :(得分:1)

对于简单易读的解决方案,请使用LINQ,GroupBy和匿名类型

string input = Console.ReadLine();

var groupedLettersOrdered = input.GroupBy(x => x, (character, charCollection) =>
    new {Character = character, Count = charCollection.Count()})
    .OrderBy(x => x.Character);
foreach(var letterGroup in groupedLettersOrdered)
    Console.WriteLine("Character {0}, Count: {1}", letterGroup.Character, letterGroup.Count);

然而Dictionary<char, int>解决方案对于大字符串来说(应该)更快更好

答案 3 :(得分:0)

首先考虑一个字符具有二进制表示(序列1和0),就像标量值一样。还要考虑对于像英语这样的拉丁字母,其等价物的字母顺序和数字顺序相对应。

所以......你可以这样做:

  1. 定义一个足够大小的int数组,以容纳所有可能的字符值(任意地,我们可以为UTF-8字符串设置256)。
  2. 遍历字符串中的每个字符;对于每个字符,将字符转换为其等效的整数,将其用作数组的索引并增加该索引处的值。
  3. 迭代数组,对于每个非零元素,打印出数组索引的字符等价物和元素的内容(字符数)

        string myString = "the quick brown fox jumps over the lazy dog";
        byte[] bytes = Encoding.UTF8.GetBytes(myString);
        int[] counts = new int[256];
        foreach (var b in bytes)
        {
            counts[(int)b]++;
        }
        for (int i = 0; i < 256; i++)
        {
            if (counts[i] > 0)
            {
                Console.WriteLine("{0} - {1}", (char)(byte)i, counts[i]);
            }
        }
    
  4. 通过在myString.ToUpper()上执行GetBytes,可以很容易地推广上述解决方案以忽略大小写。要概括为Unicode会有一些工作,因为你必须以正确的字节顺序配对字节。