C# 计算文本文件中特定单词的频率

C# 计算文本文件中特定单词的频率,c#,.net,regex,vb.net,text,C#,.net,Regex,Vb.net,Text,我有一个文本文件存储为字符串变量。对文本文件进行处理,使其仅包含小写单词和空格。现在,假设我有一个静态字典,它只是一个特定单词的列表,我想从文本文件中计算字典中每个单词的频率。例如: Text file: i love love vb development although i m a total newbie Dictionary: love, development, fire, stone 我想看到的输出如下,列出了字典中的单词及其计数。如果它使编码更简单,那么它也只能列出文本中

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

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

============
使用正则表达式eg\w+我可以得到所有匹配的单词,但是我不知道如何得到字典中的计数,所以我被卡住了。这里的效率至关重要,因为字典相当大,约100000个单词,文本文件也不小,每个都约200kb


我感谢任何帮助

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

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

foreach (var word in file)
  if (dict.ContainsKey(word))
    dict[word]++;
  else
    dict[word] = 1;
Dictionary<string, int> count =
  theString.Split(' ')
  .GroupBy(s => s)
  .ToDictionary(g => g.Key, g => g.Count());

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

您可以对字符串中的单词进行计数,方法是将它们分组并将其转换为字典:

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

现在,您只需检查字典中是否存在这些单词,并显示是否存在的计数。

使用Groovy regex facilty,我将按照以下步骤进行操作:-

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
}

使用Groovy regex facilty,我将按如下方式执行:-

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
}

试试这个。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);

试试这个。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);

可能类似于将字符串拆分为数组或列表,然后迭代/处理列表?您已经将其标记为c和vb.net。是哪一个?FWIW,在这里使用正则表达式来匹配单词不是一个好主意,特别是因为您在问题中指出输入仅为干净的小写字母和空格。改用String.Split。除此之外,这确实是一个微不足道的问题。在.NET文档中查找字典。@pcantin:这些天他们在家庭作业中使用100000字字典吗?诚然,对我来说,大学已经是30年前的事了,但对于家庭作业来说,这似乎还是太大太详细了…?@rbaryyoung,因为你可以很容易地从古腾堡计划下载一本完整的字典,没有真正的理由不使用它。可能类似于将字符串拆分为数组或列表,然后迭代/处理列表?您已经将其标记为c和vb.net。是哪一个?FWIW,在这里使用正则表达式来匹配单词不是一个好主意,特别是因为您在问题中指出输入仅为干净的小写字母和空格。改用String.Split。除此之外,这确实是一个微不足道的问题。在.NET文档中查找字典。@pcantin:这些天他们在家庭作业中使用100000字字典吗?诚然,对我来说,大学已经是30年前的事了,但对于家庭作业来说,这似乎仍然非常庞大和详细…?@rbaryyoung因为你可以很容易地从古腾堡计划下载一本完整的字典,所以没有真正的理由不使用它。