#c_sharp #list
Есть список слов. Хочу получить результирующий словарь в котором я бы мог получить количество одинаковых строк. Т.е. словарь будет содержать {слово;количество совпадений}. Данный код делает это, но ооочень медленно. Что я не так сделал, что оно так тормозит var file = File.ReadAllLines(@"1.txt").ToList(); var result = file .Select(str => new { Name = str, Count = file.Count(s => s == str) }) .Where(obj => obj.Count > 1) .Distinct() .ToDictionary(obj => obj.Name, obj => obj.Count);
Ответы
Ответ 1
Воспользуйтесь словарем. Он обеспечивает быстрый поиск по ключу. В данном случае мы будем проверять существует ли слово в словаре. Если не существует — добавляем его, а счетчик устанавливаем в 1. И если существует — делаем поиск по ключу и увеличиваем счетчик на 1. Главной особенностью словарей, является то, что они имеют уникальные ключи, которые получаются путем извлечения хэш-кода значения. Формируется таблица хэш-кодов, которая обеспечивает быстрый поиск. var dict = new Dictionary(); foreach (var line in File.ReadLines(@"1.txt")){ if (dict.ContainsKey(line)){ dict[line]++; } else { dict.Add(line, 1); } } Как подсказал @VladD По идее, лучше обойтись без материализации списка: ReadLines вместо ReadAllLines. Сложность выполнения вашего кода будет равна O(N^2), а при использовании словаря — O(N). Ответ 2
Ну да, будет тормозить, у вас квадратичный алгоритм. Вы на каждой итерации перечитываете список заново. Вам поможет GroupBy: File.ReadLines(path) .GroupBy(s => s) .ToDictionary(g => g.Key, g => g.Count()) Если вам нужно выкинуть уникальные строки, нужно немного длиннее: File.ReadLines(path) .GroupBy(s => s) .Select(g => (value: g.Key, count: g.Count())) .Where(t => t.count > 1) .ToDictionary(t => t.value, t => t.count)
Комментариев нет:
Отправить комментарий