Оптимизировать программу на поиск одинаковых вхождений - C#
Формулировка задачи:
Всем привет!
Ребята, помогите пожалуйста ускорить быстродействие программы.
Нужно найти Топ-50 повторяющихся слов из текста и выводить их на экран в отсортированном виде. Пока что мне удалось добраться до заполнения словаря, но к сожалению он сортируется по алфавиту, а надо по значению.
Если добавить еще цикл, который получит и все Values словаря и отсортирует их, а потом еще раз foreach пройтись по ContainsValue() - это еще больше затормозит программу.
Будьте добры подсказать более оптимальное решение задачи, очень буду рад увидеть альтернативные решения.
Листинг программы
- using System;
- using System.Collections.Generic;
- using System.Collections;
- using System.Text;
- using System.IO;
- using System.Text.RegularExpressions;
- using System.Linq;
- /*1. посчитать, сколько раз = каждое = слово встречается в заданном тексте.
- текст берётся из файла (например, это может быть текст романа "война и мир").
- перед подсчётами необходимо избавиться от знаков пунктуации в тексте!
- результаты сохранить в любую коллекцию, поддерживающую хранение ключей-значений.
- вывести на экран топ-100 наиболее часто встречающихся слов, длиной от 5 символов и более.
- Проверяем существует ли слово в массиве, если да, то подымаем счетчик.*/
- namespace dNET_17
- {
- class NotationFilter : StreamReader
- {
- string path;
- public StringBuilder newstr = new StringBuilder();
- Encoding encode;
- SortedDictionary<string, int> dic = new SortedDictionary<string, int>();
- List<string> keys = new List<string>();
- List<int> values = new List<int>();
- public NotationFilter(string _path, Encoding enc)
- : base(_path)
- {
- path = _path;
- encode = enc;
- }
- public static int GetOccurenceCount(string text, string search, StringComparison option = StringComparison.Ordinal)
- {
- // Console.WriteLine(String.Format("{0}", text));
- return Regex.Matches(String.Format("{0}", text), @"\b\w+\b").Cast<Match>().Select(x => x.Value).Count(x => x.Equals(search, option));
- }
- public void ShowText(string str)
- {
- for (int i = 0; i < str.Length; i++) // убираю знаки препинания
- {
- if (!(str[i] >= (char)33 && str[i] <= (char)47) && str[i] != ';' && str[i] != ':' && str[i] != '?')
- {
- newstr.Append(str[i]);// Console.Write(str[i]);
- }
- }
- string st = newstr.ToString().ToLower();
- // string[] star = newstr.ToString().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
- // Создаю список с набором слов, при этом убираю все пробелы в тексте.
- List<string> list = new List<string>(st.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
- list.Sort();
- foreach(string i in list)
- {
- if (!dic.ContainsKey(i))
- try
- {
- dic.Add(i, GetOccurenceCount(st, i));
- }
- catch
- { }
- }
- Console.WriteLine();
- }
- static void Main()
- {
- string path = ".\\x1.txt";
- DateTime time = DateTime.Now;
- NotationFilter not = new NotationFilter(path, Encoding.UTF8);
- string text = not.ReadToEnd();
- not.ShowText(text);
- Console.WriteLine("done!");
- // Console.WriteLine(not.newstr);
- Console.WriteLine(DateTime.Now - time);
- foreach (var entry in not.dic)
- {
- Console.WriteLine("[{0} : {1}]", entry.Key, entry.Value);
- }
- }
- }
- }
Решение задачи: «Оптимизировать программу на поиск одинаковых вхождений»
textual
Листинг программы
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- namespace ConsoleApplication202
- {
- class Program
- {
- static void Main(string[] args)
- {
- var parser = new FileParser();
- parser.Parse("c:\\1.txt");
- foreach (var wordFreq in parser.GetTopFrequency(5).Take(100))
- Console.WriteLine("{0}: {1}", wordFreq.Key, wordFreq.Value);
- Console.ReadKey();
- }
- }
- class FileParser
- {
- private Dictionary<string, int> wordFrequency = new Dictionary<string, int>();
- public void Parse(string fileName)
- {
- foreach(var line in File.ReadLines(fileName))
- foreach(Match m in Regex.Matches(line, @"\w+"))
- {
- var word = m.Value.ToLower();
- var counter = 0;
- wordFrequency.TryGetValue(word, out counter);
- counter++;
- wordFrequency[word] = counter;
- }
- }
- public IEnumerable<KeyValuePair<string, int>> GetTopFrequency(int minLength)
- {
- return wordFrequency.Where(pair => pair.Key.Length >= minLength).OrderBy(pair => -pair.Value);
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д