提问者:小点点

文件读取和单词计数


我想读一个文件,然后读一串单词或句子,并单独计算这些单词在文件中出现的次数。
示例输入:
filename.txt
Powerful月亮森林天空
示例输出:
Powerful:2
月亮:3
森林: 4
未使用:天空
我有点被困在这里,这就是我得到的

string filename = Console.ReadLine();
        StreamReader stream = File.OpenText(filename);
       
        string input = Console.ReadLine();
        string[] source = filename.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
        var matchQuery = from word in source
                         where word.ToLowerInvariant() == input.ToLowerInvariant()
                         select word;
        int wordCount = matchQuery.Count();
        Console.WriteLine("{0} occurrences(s) of the search term \"{1}\" were found.", wordCount, input);

共2个答案

匿名用户

做这件事有很多方法。其中一个是按Arshad评论的查询分组。如果您逐行读取文件,您也可以使用字典来保存结果。这里有一个例子,但是你必须根据你的要求来调整它:https://stackoverflow.com/a/11967649/7226070

匿名用户

我建议匹配,而不是在空白和标点符号上分割(请注意,我们有很多空白)。如果我们把单词定义为

单词是非空的字母序列

我们可以使用一个简单的正则表达式模式:

 \p{L}+

然后你可以预处理文件:

 using System.IO;
 using System.Linq;
 using System.Text.RegularExpressions;

 ...

 Regex regex = new Regex(@"\p{L}+");

 var freqs = File
   .ReadLines(filename)
   .SelectMany(line => regex
      .Matches(line)
      .Cast<Match>()
      .Select(match => match.Value))
   .GroupBy(word => word, StringComparer.OrdinalIgnoreCase)
   .ToDictionary(group => group.Key, group => group.Count());

用户查询时间。同样,我们匹配单词,然后在freqs的帮助下查找发生率:

  var result = regex
    .Matches(Console.ReadLine())
    .Cast<Match>()
    .Select(match => match.Value)
    .Distinct(StringComparer.OrdinalIgnoreCase)
    .Select(word => $"{(freqs.TryGetValue(word, out int count) ? count : 0)} occurrences(s) of {word} found");

  Console.Write(string.Join(Environment.NewLine, result));