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;
        }
    }
}

Ответы (0 шт):