【问题标题】:Count same string count out of massive string list从海量字符串列表中计算相同的字符串计数
【发布时间】:2012-01-12 11:15:28
【问题描述】:

我有超过 60 万行字符串。我想对相同的字符串进行分组并了解它们的计数。

例子

i go to school
i like music
i like games
i like music
i like music
i like games
i like music

所以结果会是

i go to school , 1
i like games  , 2
i like music , 4

我怎样才能以最快的方式做到这一点?

【问题讨论】:

    标签: c# string list c#-4.0 linq-group


    【解决方案1】:

    GroupBy 方法是您想要的。您需要将字符串放在列表中或实现IEnumerable<string> 的东西中。 spender 建议的File.ReadLines 将返回一个IEnumerable<string>,它会逐行读取文件。

    var stringGroups = File.ReadLines("filename.txt").GroupBy(s => s);
    foreach (var stringGroup in stringGroups)
        Console.WriteLine("{0} , {1}", stringGroup.Key, stringGroup.Count());
    

    如果您希望它们按从小到大的顺序排列(如您的示例所示),只需添加 OrderBy

    ...
    foreach (var stringGroup in stringGroups.OrderBy(g => g.Count()))
        ...
    

    【讨论】:

    • 是的,我也可以逐行阅读,但在这种情况下,最好的方法是什么?
    • 行是如何存储的?在一个文件中? File.ReadLines 是你的朋友。它返回可用于 LINQ 语句的 IEnumerable<string>,但不会将整个文件加载到内存中。 msdn.microsoft.com/en-us/library/dd383503.aspx
    • @Ray from .net4 您逐行阅读的方法是多余的。请参阅我之前的评论。
    • @spender,亲爱的!我实际上尝试了我的代码,但它仍然没有工作。将添加您的建议。
    【解决方案2】:

    你可以使用Linq来实现它

    IEnumerable<string> stringSource = File.ReadLines("C:\\file.txt");
    
    var result = stringSource
        .GroupBy(str => str)
        .Select(group => new {Value = group.Key, Count = group.Count()})
        .OrderBy(item => item.Count)
        .ToList();
    
    foreach(var item in result)
    {
        // item.Value - string value
        // item.Count - count
    }
    

    【讨论】:

    • 试过了,但没有订购 :) 那么如何按数量订购呢?
    • 非常感谢您更新问题。
    【解决方案3】:

    你可以试试这个:

    
    var groupedLines = System.IO.File.ReadAllLines(@"C:\temp\samplelines.txt").GroupBy(x=>x);
    groupedLines.ToList().ForEach(y => Console.WriteLine("Content: {0} - Occurences: {1}", y.Key, y.Count()));
    
    

    【讨论】:

      【解决方案4】:

      另一种“老派”方法是迭代所有行并将它们添加到字典中(如果还没有的话)。关键是行,值是计数。

      var d = new Dictionary<string, Int32>();
      foreach (var line in File.ReadAllLines(@"C:\Temp\FileName.txt"))
           if (d.ContainsKey(line)) d[line]++; else d.Add(line, 1);
      

      优点是,它也适用于早期的框架版本。

      【讨论】:

      • 你确定 ReadAllLines 到“我有超过 600k 行字符串”是个好主意吗?
      • @Viacheslav Smityukh:这个问题与IO无关,实际上OP只说他 600k行。我的 ReadAllLines 只是关于如何从文件系统获取它们的示例。我可以轻松地从我的答案中删除该行。
      • Ray 解决方案的运行速度极快 :) 但感谢您的回答。
      • @Viacheslav Smityukh:无论如何,改用ReadLines 可能比ReadAllLInes 更快。但它是 4.0 的方法,只有在返回整个集合之前开始枚举字符串集合时才会更快。
      • GroupBy 使用 Lookup 无论如何都使用哈希表。 stackoverflow.com/questions/8775395/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 2017-04-17
      • 2017-12-05
      • 2021-09-28
      相关资源
      最近更新 更多