【问题标题】:Duplicated output when counting chars in a string with Linq使用 Linq 计算字符串中的字符时重复输出
【发布时间】:2016-04-13 11:08:00
【问题描述】:

我在输出此代码时遇到了这个问题,该代码输出了字符串中某个字符被提及的次数。

class Program
{
    static void Main(string[] args)
    {
        string str = Console.ReadLine().ToLower();
        string sortedString = String.Concat(str.OrderBy(c => c));

        foreach (char ch in sortedString)
        {
            Console.WriteLine($"{ch} => {str.Count(x => x == ch)}");
        }
    }
}

这是我得到的输出:

Alabala
a => 4
a => 4
a => 4
a => 4
b => 1
l => 2
l => 2

这是我想要得到的输出

Alabala
a => 4
b => 1
l => 2

如果有人帮助我,将不胜感激。

【问题讨论】:

  • 它按字母顺序对 str 字符串进行排序。因此,如果输入是“Alabala”,则排序为“aaaabll”

标签: c# string linq duplicates chars


【解决方案1】:

您可以使用ToDictionary()OrderBy()Distinct() 方法的组合:

        string str = "halleluyah";

        var grouppedChars = str
            .Distinct()       // removes duplicates
            .OrderBy(c => c)  // orders them alphabetically
            .ToDictionary(    // converts to dictionary [string, int]
                c => c,
                c => str.Count(c2 => c2 == c));

        foreach (var group in grouppedChars)
        {
            Console.WriteLine($"{group.Key} => {group.Value}");
        }

        Console.ReadKey();

输出:

a => 2
e => 1
h => 2
l => 3
u => 1
y => 1

附: 这比GroupBy() 更好,因为您真的不想将这些字符分组在某个地方,而是只保留它们的数量。

方法二,用char信息添加自己的结构体:

        struct CharStatistics
        {
           public readonly char @char;
           public readonly int count;

           public CharStatistics(char @char, int count)
           {
              this.@char = @char;
              this.count = count;
           }
        }

在主方法中:

        string str = "halleluyah";

        var charsInfo = str
            .OrderBy(c => c)
            .Distinct()
            .Select(c =>
                new CharStatistics(c, str.Count(c2 => c2 == c)));

        foreach (var stats in charsInfo)
        {
            Console.WriteLine($"{stats.@char} => {stats.count}");
        }

【讨论】:

    【解决方案2】:

    您可以在单个 linq 中执行此操作,如下所示:

    string str =  Console.ReadLine().ToLower();
    string sortedString = String.Concat(str.OrderBy(c => c));
    
    var result = sortedString.GroupBy(x => x)
                             .Select(y => string.Format("{0} => {1}", y.Key, y.Count())).ToList();
    
    foreach (var output in result)
    {
        Console.WriteLine(output);
    }
    

    【讨论】:

    • 您可以将sortedString 简化为:var sortedString = str.OrderBy(c => c); - 无需将其转回字符串。同样,您可能会丢失ToList()
    • 是的:)。我刚刚更新了结果部分。而 orderBy 可以是单个 linq 的一部分
    • 如果你想发疯,你可以写:var result = str.OrderBy(c => c).GroupBy(x => x).Select(y => $"{y.Key} => {y.Count()}"); ;)
    猜你喜欢
    • 2020-08-17
    • 2012-05-31
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    相关资源
    最近更新 更多