【问题标题】:Counting the Frequency of Specific Words in Text File计算文本文件中特定单词的频率
【发布时间】:2011-05-30 02:01:15
【问题描述】:

我有一个存储为字符串变量的文本文件。处理文本文件,使其仅包含小写单词和空格。现在,假设我有一个静态字典,它只是一个特定单词的列表,我想从文本文件中计算字典中每个单词的频率。例如:

Text file:

i love love vb development although i m a total newbie

Dictionary:

love, development, fire, stone

我希望看到的输出类似于以下内容,列出了字典中的单词及其计数。如果它使编码更简单,它也可以只列出文本中出现的字典单词。

===========

WORD, COUNT

love, 2

development, 1

fire, 0

stone, 0

============

使用正则表达式(例如“\w+”)我可以获得所有单词匹配,但我不知道如何获得字典中的计数,所以我被卡住了。效率在这里至关重要,因为字典很大(约 100,000 个单词),文本文件也不小(每个约 200kb)。

感谢任何帮助。

【问题讨论】:

  • 可能类似于将字符串拆分为ArrayList,然后迭代/处理列表?
  • 您已将其标记为 c# 和 vb.net。是哪个?
  • FWIW,在这里使用正则表达式来匹配单词不是一个好主意,特别是因为您在问题中指出输入是干净的(仅小写字母和空格。)使用 String.Split 代替.除此之外,这确实是一个微不足道的问题。在 .NET 文档中查找字典。
  • @pcantin:现在他们在家庭作业中使用 100,000 字的字典吗?诚然,大学对我来说是 30 年前的事了,但对于家庭作业来说,这似乎仍然非常庞大和详细......?
  • @RBarryYoung 因为您可以轻松地从 Project Gutenberg 下载完整的字典,所以没有真正的理由不使用它。

标签: c# .net regex vb.net text


【解决方案1】:
var dict = new Dictionary<string, int>();

foreach (var word in file)
  if (dict.ContainsKey(word))
    dict[word]++;
  else
    dict[word] = 1;

【讨论】:

    【解决方案2】:

    您可以通过将字符串中的单词分组并将其转换为字典来计数:

    Dictionary<string, int> count =
      theString.Split(' ')
      .GroupBy(s => s)
      .ToDictionary(g => g.Key, g => g.Count());
    

    现在您可以检查字典中是否存在单词,如果存在则显示计数。

    【讨论】:

      【解决方案3】:

      使用 Groovy 正则表达式工具,我会这样做:-

      def input="""
          i love love vb development although i m a total newbie
      """
      
      def dictionary=["love", "development", "fire", "stone"]
      
      
      dictionary.each{
          def pattern= ~/${it}/
          match = input =~ pattern
          println "${it}" + "-"+ match.count
      }
      

      【讨论】:

        【解决方案4】:

        试试这个。 words 变量显然是您的文本字符串。关键字数组是您要统计的关键字列表。

        对于不在文本中的字典单词,这不会返回 0,但您指定此行为是可以的。这应该会在满足应用程序要求的同时为您提供相对较好的性能。

        string words = "i love love vb development although i m a total newbie";
        string[] keywords = new[] { "love", "development", "fire", "stone" };
        
        Regex regex = new Regex("\\w+");
        
        var frequencyList = regex.Matches(words)
            .Cast<Match>()
            .Select(c => c.Value.ToLowerInvariant())
            .Where(c => keywords.Contains(c))
            .GroupBy(c => c)
            .Select(g => new { Word = g.Key, Count = g.Count() })
            .OrderByDescending(g => g.Count)
            .ThenBy(g => g.Word);
        
        //Convert to a dictionary
        Dictionary<string, int> dict = frequencyList.ToDictionary(d => d.Word, d => d.Count);
        
        //Or iterate through them as is
        foreach (var item in frequencyList)
            Response.Write(String.Format("{0}, {1}", item.Word, item.Count));
        

        如果你想在不使用 RegEx 的情况下实现相同的目的,因为你表示你知道所有内容都是小写并用空格分隔,你可以像这样修改上面的代码:

        string words = "i love love vb development although i m a total newbie";
        string[] keywords = new[] { "love", "development", "fire", "stone" };
        
        var frequencyList = words.Split(' ')
            .Select(c => c)
            .Where(c => keywords.Contains(c))
            .GroupBy(c => c)
            .Select(g => new { Word = g.Key, Count = g.Count() })
            .OrderByDescending(g => g.Count)
            .ThenBy(g => g.Word);
        
        Dictionary<string, int> dict = frequencyList.ToDictionary(d => d.Word, d => d.Count);
        

        【讨论】:

          猜你喜欢
          • 2017-03-29
          • 1970-01-01
          • 2016-01-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-14
          • 1970-01-01
          相关资源
          最近更新 更多