C# Задача с Dictionary. Оптимизация кода. Критика решения
Как Оптимизировать код? Если он плох то насколько? Читаем ли он? Что по производительности? Как пользуясь другими вспомогательными переменными сделать программу быстрее, читабельнее? GetMostFrequentNextWords - поле битвы, MAIN чисто для проверки примера. Без Linq!
Суть задания :
N-грамма — это N соседних слов в одном предложении. 2-граммы называют биграммами. 3-граммы — триграммами.
Например, из текста: "She stood up. Then she left." можно выделить следующие биграммы "she stood", "stood up", "then she" и "she left", но не "up then". И две триграммы "she stood up" и "then she left", но не "stood up then".
По списку предложений (список состоит из слов собранных в списки предложений) составьте словарь самых частотных продолжений биграмм и триграмм. Это словарь, ключами которого являются все возможные начала биграмм и триграмм, а значениями — их самые частотные продолжения. Если есть несколько продолжений с одинаковой частотой, используйте то, которое лексикографически меньше.
Пример По тексту "a b c d. b c d. e b c a d." должен быть составлен такой словарь:
1 "a": "b"
2 "b": "c"
3 "c": "d"
4 "e": "b"
5 "a b": "c"
6 "b c": "d"
7 "e b": "c"
8 "c a": "d"
Из двух биграмм "a b" и "a d", встречающихся однократно, в словаре есть только пара "a": "b", как лексикографически меньшая. из двух встречающихся в тексте биграмм "c d" и "c a" в словаре есть только более частотная пара "c": "d". из двух триграмм "b c d" и "b c a" в словаре есть только более частотная "b c": "d".
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp11
{
public static class SentencesParserTask
{
static void Main(string[] args)
{
//a b c d. b c d. e b c a d.
var list = new List<List<string>>();
list.Add(new List<string>());
list[0].Add("a");
list[0].Add("b");
list[0].Add("c");
list[0].Add("d");
list.Add(new List<string>());
list[1].Add("b");
list[1].Add("c");
list[1].Add("d");
list.Add(new List<string>());
list[2].Add("e");
list[2].Add("b");
list[2].Add("c");
list[2].Add("a");
list[2].Add("d");
Console.WriteLine("The origin text : \n" );
foreach (var sentence in list)
{
foreach(var word in sentence)
{
Console.Write(" " + word);
}
Console.Write(".");
}
Console.Write("\n\n ");
Console.WriteLine("Expected output: \n1 a: b \n2 b: c \n3 c: d \n4 e: b \n5 a b: c \n6 b c: d \n7 e b: c \n8 c a: d \n\n ");
var dictionary = new Dictionary<string, string>(GetMostFrequentNextWords(list));
int index = 1;
Console.WriteLine("Your output (THE ORDER ISNT IMPORTANT) :");
foreach (var keyValuePair in dictionary)
{
Console.WriteLine(index++ + " " + keyValuePair.Key + ": " + keyValuePair.Value);
}
Console.ReadLine();
}
public static Dictionary<string, string> GetMostFrequentNextWords(List<List<string>> text)
{
var result = new Dictionary<string, string>();
var helpDictionary = new Dictionary<string, Dictionary<string, int>>();
for (int i = 0; i < text.Count; i++)
{
for (int j = 0; j < text[i].Count; j++)
{
if (text[i].Count - j >= 3)
{
string keyTwoWords = text[i][j] + " " + text[i][j + 1];
if (!helpDictionary.ContainsKey(keyTwoWords))
helpDictionary[keyTwoWords] = new Dictionary<string, int>();
if (!helpDictionary[keyTwoWords].ContainsKey(text[i][j + 2]))
helpDictionary[keyTwoWords][text[i][j + 2]] = 0;
helpDictionary[keyTwoWords][text[i][j + 2]]++;
}
if (text[i].Count - j >= 2)
{
if (!helpDictionary.ContainsKey(text[i][j]))
helpDictionary[text[i][j]] = new Dictionary<string, int>();
if (!helpDictionary[text[i][j]].ContainsKey(text[i][j + 1]))
helpDictionary[text[i][j]][text[i][j + 1]] = 0;
helpDictionary[text[i][j]][text[i][j + 1]]++;
}
}
}
foreach (KeyValuePair<string, Dictionary<string, int>> keyValuePair in helpDictionary)
{
if (!result.ContainsKey(keyValuePair.Key))
result[keyValuePair.Key] = "";
int maxFrequencyCount = 0;
string maxFrequencyString = "";
foreach (KeyValuePair<string, int> keyValuePairInternal in keyValuePair.Value)
{
if ((keyValuePairInternal.Value > maxFrequencyCount) || ((keyValuePairInternal.Value == maxFrequencyCount) &&
(string.CompareOrdinal(maxFrequencyString, keyValuePairInternal.Key) > 0)))
{
result[keyValuePair.Key] = keyValuePairInternal.Key;
maxFrequencyCount = keyValuePairInternal.Value;
maxFrequencyString = keyValuePairInternal.Key;
}
}
}
return result;
}
}
}