Оптимизировать программу на поиск одинаковых вхождений - 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);
}
}
}