Подсчет частоты конкретных слов в текстовом файле

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

Text file: i love love vb development although ima total newbie Dictionary: love, development, fire, stone 

Результат, который я хотел бы увидеть, выглядит следующим образом: перечисление словарного слова и его счетчика. Если это упрощает кодирование, оно также может отображать только слова слова, которые появились в тексте.

 =========== WORD, COUNT love, 2 development, 1 fire, 0 stone, 0 ============ 

Используя регулярное выражение (например, «\ w +»), я могу получить все совпадения слов, но я не знаю, как получить подсчеты, которые также находятся в словаре, поэтому я застрял. Эффективность здесь важна, поскольку словарь довольно велик (~ 100 000 слов), а текстовые файлы также не малы (~ 200 кбайт каждый).

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

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

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

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

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

Используя Groovy regex facilty, я сделал бы это, как показано ниже:

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

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

Это не вернет слова для словаря 0, которые не указаны в тексте, но вы указали, что это поведение в порядке. Это должно дать вам относительно хорошую производительность при выполнении требований вашего приложения.

 string words = "i love love vb development although ima total newbie"; string[] keywords = new[] { "love", "development", "fire", "stone" }; Regex regex = new Regex("\\w+"); var frequencyList = regex.Matches(words) .Cast() .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 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 ima 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 dict = frequencyList.ToDictionary(d => d.Word, d => d.Count);