Подсчет частоты определенных слов в текстовом файле - PullRequest
1 голос
/ 23 декабря 2010

У меня есть текстовый файл, хранящийся в виде строковой переменной. Текстовый файл обрабатывается так, что он содержит только строчные слова и пробелы. Теперь, скажем, у меня есть статический словарь, который представляет собой просто список определенных слов, и я хочу посчитать из текстового файла частоту каждого слова в словаре. Например:

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 слов) и текстовые файлы тоже не маленькие (~ 200 КБ каждый).

Я ценю любую помощь.

Ответы [ 4 ]

6 голосов
/ 23 декабря 2010

Вы можете посчитать слова в строке, сгруппировав их и превратив в словарь:

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

Теперь вы можете просто проверить, существуют ли слова в словаре, и показать количество, если оно есть.

5 голосов
/ 23 декабря 2010
var dict = new Dictionary<string, int>();

foreach (var word in file)
  if (dict.ContainsKey(word))
    dict[word]++;
  else
    dict[word] = 1;
0 голосов
/ 23 декабря 2010

Попробуй это.Переменная слов, очевидно, является вашей строкой текста.Массив ключевых слов - это список ключевых слов, которые вы хотите сосчитать.

Это не вернет 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);
0 голосов
/ 23 декабря 2010

Используя 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...