Beispiel #1
0
        static void Main(string[] args)
        {
            //string path = @"C:\Users\Risha\Desktop\text.txt";

            string a    = "";
            string word = "";
            Porter p    = new Porter();

            Console.WriteLine("Введите адрес исходного файла: ");
            string path = Console.ReadLine();

            while (true)
            {
                Console.WriteLine("Введите слово:");

                string input = Console.ReadLine();

                if (input != "выйти")
                {
                    Console.WriteLine("Основа слова " + "input " + ": " + p.Stemm(input));
                }
                else
                {
                    break;
                }

                word = p.Stemm(input);
                FileStream   stream = new FileStream(@"C:\test\output.txt", FileMode.Create);
                StreamWriter writer = new StreamWriter(stream);

                try
                {
                    Console.WriteLine();
                    Console.WriteLine("Однокоренные слова в файле:");
                    using (StreamReader sr = new StreamReader(path, Encoding.Default))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            a = line;
                            if (a.IndexOf(word) > -1)
                            {
                                Console.WriteLine(a);
                                writer.WriteLine(a);
                            }
                        }
                    }
                    Console.WriteLine();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                writer.Close();
            }
        }
 public void DictionaryTest()
 {
     var dict = Resource.StemmingRussianPorterDictionary
         .Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
         .Select(s =>
             {
                 var split = s.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
                 return new { Word = split[0], Stem = split[1] };
             });
     foreach (var pair in dict)
         Assert.AreEqual(pair.Stem, Porter.Stemm(pair.Word));
 }
 public void SingleWordTest()
 {
     string[][] wordsPair = { 
                                new string[] { "Вышагивающая", "вышагива" }, 
                                new string[] { "авенантненькая", "авенантненьк" },
                                new string[] { "агамемнон", "агамемнон" },
                                new string[] { "ободрившийся", "ободр" },
                                new string[] { "следователей", "следовател" },
                            };
     foreach(var pair in wordsPair)
         Assert.AreEqual(pair[1], Porter.Stemm(pair[0]));
 }
Beispiel #4
0
        //существует в списке лематизированных слов
        private List <int> Exist(string word)
        {
            var porter = new Porter();

            //лемитизируем
            word = porter.Stemm(word);
            if (indexedDict.ContainsKey(word))
            {
                return(indexedDict[word]);
            }
            else
            {
                return(new List <int>());
            }
        }
Beispiel #5
0
        private List <int> NotExist(string word)
        {
            var porter = new Porter();

            //лемитизация без !
            word = porter.Stemm(word.Replace("!", string.Empty));
            var list = new List <int>();

            //индексы всех элементов
            for (int i = 0; i < docNum; i++)
            {
                list.Add(i);
            }
            if (indexedDict.ContainsKey(word))
            {//Операция Except возвращает последовательность, содержащую все элементы первой последовательности, которых нет во второй последовательности.
                list = list.Except(indexedDict[word]).ToList();
            }

            return(list);
        }
Beispiel #6
0
        public void delServicePartOfSpeech(ref List <string> TEXT)
        {
            //      string[] pretext = { "аля","без","безведома","безо","благодаря","близ","близкоот","в","ввиде","вблизи", "ввиду", "вглубь", "вдогон", "вдоль", "взамен", "включая", "вкруг", "вместо", "вне", "внизу", "внутри", "внутрь", "во", "вовнутрь", "возле", "вокруг", "вопреки", "вослед", "впереди", "вразрез", "вроде", "вслед", "вследствие", "встречу", "выключая", "для", "для-ради", "до", "за", "замест", "заместо", "из", "из-за", "из-под", "из-подо", "изнутри", "изо", "исключая", "к", "касаемо", "касательно", "ко", "кончая", "кроме", "кругом", "меж", "между", "мимо", "на", "наверху", "навроде", "навстречу","надо", "назад", "назади", "накануне", "наместо", "наперекор", "наперерез", "наперехват", "наподобие", "наподобье", "напротив", "насупротив", "насчёт", "несмотря", "несмотря на", "ниже", "о", "об",  "обо", "обок", "обочь", "около", "окрест", "окроме", "окромя", "округ", "опосля", "опричь", "от", "относительно", "ото", "перед", "передо", "по", "по-за", "по-над", "по-под", "повдоль", "поверх", "под", "подле", "подо", "подобно", "позади", "позадь", "позднее", "помимо", "поперёд", "поперёк", "порядка", "посверху", "посереди", "посередине", "посерёдке", "посередь", "после", "посреди", "посредине", "посредством", "пред", "предо", "преж", "прежде", "при", "про", "промеж", "промежду", "против", "противно", "противу", "путём", "ради", "с",  "сверх", "сверху", "свыше", "середи", "середь", "сзади", "скрозь", "снизу", "со", "согласно", "спустя", "среди", "средь", "сродни", "супротив", "у", "через", "черезо", "чрез"};
            //      string[] particle = { "кось", "ста", "а", "авось", "авось-либо", "ага", "адьё", "аж", "ажно", "аиньки", "аминь", "ан", "аск", "аушки", "аюшки", "б", "бишь", "будто", "буквально", "бы", "бывает", "было", "ведь", "верно", "вероятно", "вестимо", "вишь", "во", "вон", "вот", "вот-вот", "вроде", "вряд", "всё", "всё-таки", "всего", "го", "да", "давай", "давай-ка", "даже", "дак", "де", "действительно", "дескать", "добре", "дык", "едва", "если", "ещё", "ж", "же", "замётано", "и", "или", "иль", "именно", "имхо", "ин", "инда", "индо", "ино", "ить", "ишь", "ка", "кажется", "кайнэ", "как", "как бы", "конечно", "куда", "ладно", "ладушки", "ли", "лих", "лишь", "лучше", "ль", "мол", "на", "на-тка", "навроде", "накось", "накося", "наоборот", "не", "не-а", "небось", "нет", "нет-нет", "нету", "неуж", "неужели", "неужли", "неужто", "ни", "никак", "ничего", "ништо", "ну", "ну-ну", "ну-с", "отколь", "откуда", "откудова", "отож", "очевидно", "поди", "пожалуй", "пожалуйста", "пока", "с", "так", "таки", "того", "то-то", "тоже", "уж", "уже", "ужели", "хоть", "хотя", "что", "что-то", "чтоб", "чтобы", "чтой-то"};
            //      string[] union = {"а", "абы", "аж", "ажно", "ай", "аки", "ако", "али", "аль", "ан", "аще", "благо", "бо", "буде", "будто", "ведь", "впрочем", "всё", "всё-таки",  "где", "где-то", "да", "дабы", "даже", "докуда", "дотоле", "егда", "едва", "еже", "ежели", "ежель", "если", "ж", "же", "зане", "занеже", "зато", "зачем", "значит", "и", "или", "ибо", "или", "иль", "именно", "имже", "инако", "иначе", "инда", "ино", "итак", "кабы", "как", "каков", "какой", "ковда", "ковды", "когда", "когды", "коли", "коль", "который","куда", "ли","либо","лишь","ль","настолько","нежели","незомь","ни","ниже","нижли","но","обаче","однако","одначе","отколь","откуда","откудова","оттого","отчего","поелику","пока","покамест","покаместь","покеда","поколева","поколику","поколь","покуль","покуля","понеже","поскольку","пота","потолику","потому","почём","почему","правда","преж","притом","причём","просто","пускай","пусть","равно","раз","разве","ровно","тож","тоже","только","хоть","хотя","чем","чи","что","чтоб","чтобы","чуть","штоб","штобы","яко","якобы" };
            //      string[] pronoun = { "я", "мы", "ты", "вы", "он", "она", "оно", "они", "себя", "мой", "моя", "мое", "мои", "наш", "наша", "наше", "наши", "твой", "твоя", "твое", "твои", "ваш", "ваша", "ваше", "ваши", "его", "ее", "их", "кто", "что", "какой", "каков", "чей", "который", "сколько", "где", "когда", "куда", "зачем", "этот", "тот", "такой", "таков", "тут", "здесь", "сюда", "туда", "оттуда", "отсюда", "тогда", "поэтому", "сей", "оный", "затем", "столько", "весь", "всякий", "все", "сам", "самый", "каждый", "любой", "другой", "иной", "всяческий", "всюду", "везде", "всегда", "никто", "ничто", "некого", "нечего", "никакой", "ничей", "некто", "нечто", "некий", "некоторый", "несколько", "кое-кто", "кое-где", "кое-что", "кое-куда", "какой-либо", "сколько-нибудь", "куда-нибудь", "зачем-нибудь", "чей-либо" };

            // Один сплошной массив слов для удаления
            // string[] delWord = { "то", "нас", "них", "нам", "вам", "всех", "нем", "нему", "аля", "без", "безведома", "безо", "благодаря", "близ", "в", "ввиде", "вблизи", "ввиду", "вглубь", "вдогон", "вдоль", "взамен", "включая", "вкруг", "вместо", "вне", "внизу", "внутри", "внутрь", "во", "вовнутрь", "возле", "вокруг", "вопреки", "вослед", "впереди", "вразрез", "вроде", "вслед", "вследствие", "встречу", "выключая", "для", "для-ради", "до", "за", "замест", "заместо", "из", "из-за", "из-под", "из-подо", "изнутри", "изо", "исключая", "к", "касаемо", "касательно", "ко", "кончая", "кроме", "кругом", "меж", "между", "мимо", "на", "наверху", "навроде", "навстречу", "надо", "назад", "назади", "накануне", "наместо", "наперекор", "наперерез", "наперехват", "наподобие", "наподобье", "напротив", "насупротив", "насчёт", "несмотря", "несмотря на", "ниже", "о", "об", "обо", "обок", "обочь", "около", "окрест", "окроме", "окромя", "округ", "опосля", "опричь", "от", "относительно", "ото", "перед", "передо", "по", "по-за", "по-над", "по-под", "повдоль", "поверх", "под", "подле", "подо", "подобно", "позади", "позадь", "позднее", "помимо", "поперёд", "поперёк", "порядка", "посверху", "посереди", "посередине", "посерёдке", "посередь", "после", "посреди", "посредине", "посредством", "пред", "предо", "преж", "прежде", "при", "про", "промеж", "промежду", "против", "противно", "противу", "путём", "ради", "с", "сверх", "сверху", "свыше", "середи", "середь", "сзади", "скрозь", "снизу", "со", "согласно", "спустя", "среди", "средь", "сродни", "супротив", "у", "через", "черезо", "чрез", "кось", "ста", "а", "авось", "авось-либо", "ага", "адьё", "аж", "ажно", "аиньки", "аминь", "ан", "аск", "аушки", "аюшки", "б", "бишь", "будто", "буквально", "бы", "бывает", "было", "ведь", "верно", "вероятно", "вестимо", "вишь", "во", "вон", "вот", "вот-вот", "вроде", "вряд", "всё", "всё-таки", "всего", "го", "да", "давай", "давай-ка", "даже", "дак", "де", "действительно", "дескать", "добре", "дык", "едва", "если", "ещё", "ж", "же", "замётано", "и", "или", "иль", "именно", "имхо", "ин", "инда", "индо", "ино", "ить", "ишь", "ка", "кажется", "кайнэ", "как", "как бы", "конечно", "куда", "ладно", "ладушки", "ли", "лих", "лишь", "лучше", "ль", "мол", "на", "на-тка", "навроде", "накось", "накося", "наоборот", "не", "не-а", "небось", "нет", "нет-нет", "нету", "неуж", "неужели", "неужли", "неужто", "ни", "никак", "ничего", "ништо", "ну", "ну-ну", "ну-с", "отколь", "откуда", "откудова", "отож", "очевидно", "поди", "пожалуй", "пожалуйста", "пока", "с", "так", "таки", "того", "то-то", "тоже", "также", "уж", "уже", "ужели", "хоть", "хотя", "что", "что-то", "чтоб", "чтобы", "чтой-то", "а", "абы", "аж", "ажно", "ай", "аки", "ако", "али", "аль", "ан", "аще", "благо", "бо", "буде", "будто", "ведь", "впрочем", "всё", "всё-таки", "где", "где-то", "да", "дабы", "даже", "докуда", "дотоле", "егда", "едва", "еже", "ежели", "ежель", "если", "ж", "же", "зане", "занеже", "зато", "зачем", "значит", "и", "или", "ибо", "или", "иль", "именно", "имже", "инако", "иначе", "инда", "ино", "итак", "кабы", "как", "каков", "какой", "ковда", "ковды", "когда", "когды", "коли", "коль", "который", "куда", "ли", "либо", "лишь", "ль", "настолько", "нежели", "незомь", "ни", "ниже", "нижли", "но", "обаче", "однако", "одначе", "отколь", "откуда", "откудова", "оттого", "отчего", "поелику", "пока", "покамест", "покаместь", "покеда", "поколева", "поколику", "поколь", "покуль", "покуля", "понеже", "поскольку", "пота", "потолику", "потому", "почём", "почему", "правда", "преж", "притом", "причём", "просто", "пускай", "пусть", "равно", "раз", "разве", "ровно", "тож", "тоже", "только", "хоть", "хотя", "чем", "чи", "что", "чтоб", "чтобы", "чуть", "штоб", "штобы", "яко", "якобы", "я", "мы", "ты", "вы", "он", "она", "оно", "они", "себя", "мой", "моя", "мое", "мои", "наш", "наша", "наше", "наши", "твой", "твоя", "твое", "твои", "ваш", "ваша", "ваше", "ваши", "его", "ее", "их", "кто", "что", "какой", "каков", "чей", "который", "сколько", "где", "когда", "куда", "зачем", "этот", "тот", "такой", "таков", "тут", "здесь", "сюда", "туда", "оттуда", "отсюда", "тогда", "поэтому", "это", "этим", "этому", "этом", "этих", "сей", "оный", "затем", "столько", "весь", "всякий", "все", "сам", "самый", "каждый", "любой", "другой", "иной", "всяческий", "всюду", "везде", "всегда", "никто", "ничто", "некого", "нечего", "никакой", "ничей", "некто", "нечто", "некий", "некоторый", "несколько", "кое-кто", "кое-где", "кое-что", "кое-куда", "какой-либо", "сколько-нибудь", "свой", "куда-нибудь", "зачем-нибудь", "чей-либо", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "ноль", "эту" };

            // Один сплошной массив пропущенный через стример для ускорения)
            string[] delWord = { "то", "нас", "них", "нам", "вам", "всех", "н", "нему", "ал", "без", "безведом", "безо", "благодар", "близ", "в", "ввид", "вблиз", "ввиду", "вглуб", "вдогон", "вдол", "взамен", "включ", "вкруг", "вместо", "вн", "внизу", "внутр", "внутр", "во", "вовнутр", "возл", "вокруг", "вопрек", "вослед", "вперед", "вразрез", "врод", "вслед", "вследств", "встречу", "выключ", "дл", "для-рад", "до", "з", "замест", "заместо", "из", "из-з", "из-под", "из-подо", "изнутр", "изо", "исключ", "к", "касаемо", "касательно", "ко", "конч", "кром", "круг", "меж", "между", "мимо", "н", "наверху", "наврод", "навстречу", "надо", "назад", "назад", "наканун", "наместо", "наперекор", "наперерез", "наперехват", "наподоб", "наподоб", "напрот", "насупрот", "насчет", "несмотр", "несмотря", "н", "ниж", "о", "об", "обо", "обок", "обоч", "около", "окрест", "окром", "окром", "округ", "опосл", "оприч", "от", "относительно", "ото", "перед", "передо", "по", "по-з", "по-над", "по-под", "повдол", "поверх", "под", "подл", "подо", "подобно", "позад", "позад", "поздн", "помимо", "поперед", "поперек", "порядк", "посверху", "посеред", "посередин", "посередк", "посеред", "посл", "посред", "посредин", "посредств", "пред", "предо", "преж", "прежд", "пр", "про", "промеж", "промежду", "прот", "противно", "противу", "пут", "рад", "с", "сверх", "сверху", "свыш", "серед", "серед", "сзад", "скроз", "снизу", "со", "согласно", "спуст", "сред", "сред", "сродн", "супрот", "у", "через", "черезо", "чрез", "ко", "ст", "", "аво", "авось-либо", "аг", "ад", "аж", "ажно", "аиньк", "амин", "а", "аск", "аушк", "аюшк", "б", "б", "будто", "буквально", "б", "быва", "было", "вед", "верно", "вероятно", "вестимо", "в", "во", "вон", "вот", "вот-вот", "врод", "вряд", "вс", "все-так", "вс", "го", "д", "дава", "давай-к", "даж", "дак", "д", "действительно", "деска", "добр", "дык", "едв", "есл", "ещ", "ж", "ж", "замета", "", "", "ил", "именно", "имхо", "ин", "инд", "индо", "ино", "", "", "к", "кажет", "кайнэ", "как", "как", "б", "конечно", "куд", "ладно", "ладушк", "л", "лих", "л", "лучш", "ль", "мол", "н", "на-тк", "наврод", "нако", "нако", "наоборот", "н", "не-", "небо", "нет", "нет-нет", "нету", "неуж", "неужел", "неужл", "неужто", "н", "никак", "нич", "ништо", "ну", "ну-ну", "ну-с", "откол", "откуд", "откудов", "отож", "очевидно", "под", "пожал", "пожалуйст", "пок", "с", "так", "так", "т", "то-то", "тож", "такж", "уж", "уж", "ужел", "хот", "хот", "что", "что-то", "чтоб", "чтоб", "чтой-то", "", "аб", "аж", "ажно", "а", "ак", "ако", "а", "ал", "а", "ащ", "благо", "бо", "буд", "будто", "вед", "впроч", "вс", "все-так", "гд", "где-то", "д", "даб", "даж", "докуд", "дотол", "егд", "едв", "еж", "ежел", "ежел", "есл", "ж", "ж", "зан", "занеж", "зато", "зач", "значит", "", "", "ибо", "", "ил", "именно", "имж", "инако", "инач", "инд", "ино", "итак", "каб", "как", "как", "как", "ковд", "ковд", "когд", "когд", "кол", "кол", "котор", "куд", "л", "либо", "л", "ль", "настолько", "нежел", "незом", "н", "ниж", "нижл", "но", "обач", "однако", "однач", "откол", "откуд", "откудов", "отт", "отч", "поелику", "пок", "покамест", "покамест", "покед", "поколев", "поколику", "покол", "покул", "покул", "понеж", "поскольку", "пот", "потолику", "потому", "поч", "почему", "правд", "преж", "прит", "прич", "просто", "пуска", "пуст", "равно", "раз", "разв", "ровно", "тож", "тож", "только", "хот", "хот", "ч", "ч", "что", "чтоб", "чтоб", "чут", "штоб", "штоб", "яко", "якоб", "", "м", "т", "в", "он", "он", "оно", "он", "себ", "м", "мо", "м", "мо", "наш", "наш", "наш", "наш", "тв", "тво", "тв", "тво", "ваш", "ваш", "ваш", "ваш", "", "", "их", "кто", "что", "как", "как", "ч", "котор", "сколько", "гд", "когд", "куд", "зач", "этот", "тот", "так", "так", "тут", "зд", "сюд", "туд", "оттуд", "отсюд", "тогд", "поэтому", "это", "эт", "этому", "эт", "этих", "с", "он", "зат", "столько", "в", "всяк", "вс", "сам", "сам", "кажд", "люб", "друг", "ин", "всяческ", "всюду", "везд", "всегд", "никто", "ничто", "нек", "неч", "никак", "нич", "некто", "нечто", "нек", "некотор", "несколько", "кое-кто", "кое-гд", "кое-что", "кое-куд", "какой-либо", "сколько-нибуд", "св", "куда-нибуд", "зачем-нибуд", "чей-либо", "один", "дв", "тр", "четыр", "пя", "шест", "сем", "восем", "девя", "нол", "нашу", "эту", "сих", "тому", "там", "таких", "тех", "над", "вас" };

            string s = null;

            s = System.Text.RegularExpressions.Regex.Replace(TEXT[8], @"[-\.!,\s:;?(<)>«»—1234567890""%#@&'']", " "); // Убераем все знаки из текста


            List <string> WordsP = new List <string>();
            List <string> Words  = new List <string>();

            String[] words = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Разбиваем весь текст на массив слов


            string T    = null;
            string text = null;


            for (int i = 0; i < words.Length; i++)
            {
                text = text + " " + words[i];
            }

            foreach (var k in words)
            {
                Words.Add(k);
            }

            Console.WriteLine(Words.Count);

            // Применение Стремера портера для удаления частиц и тд


            Porter p = new Porter();

            // string itemP=null;
            //  string WordsP=null;


            //



            for (int k = 0; k < words.Length; k++)
            {
                WordsP.Add(p.Stemm(words[k]));
            }



            foreach (var item in delWord)
            {
                //    itemP = p.Stemm(item); //слово для удаления пропущенное через парсер



                for (int i = 0; i < WordsP.Count; i++)
                {
                    //       WordsP = p.Stemm(Words[i]); // анализируемое слово  пропущенное через парсер



                    if (item == WordsP[i])
                    {
                        WordsP.Remove(WordsP[i]);
                        Words.Remove(Words[i]);
                        i--;
                    }
                }
            }

            Console.WriteLine(Words.Count);

            text = null;
            for (int i = 0; i < Words.Count; i++)
            {
                text = text + " " + Words[i];
            }
            Console.WriteLine(text);

            // Console.WriteLine(text);
        }
Beispiel #7
0
        public void SearchWord(string query)
        {
            var countDocument = 100;
            var porter        = new Porter();
            var words         = query.Split(' ').Select(x => porter.Stemm(x)).ToArray();
            var length        = words.Length;
            var tfs           = new double[length];

            //определяем tf поисковых слов
            for (int i = 0; i < length; i++)
            {
                var count = words.Where(x => x == words[i]).Count();
                tfs[i] = (double)count / length;
            }

            //определяем tdf поисковых слов
            var idfs = new double[length];

            for (int i = 0; i < length; i++)
            {
                if (invertDict.ContainsKey(words[i]))
                {
                    idfs[i] = Math.Log10(countDocument / invertDict[words[i]].Count);
                }
                else
                {
                    idfs[i] = 0;
                }
            }

            //определяем td-idf
            var tfIdf = new Dictionary <string, double>();

            for (int i = 0; i < length; i++)
            {
                tfIdf.Add(words[i], tfs[i] * idfs[i]);
            }

            //Рассчитаем длину запроса
            var queryLenght = Math.Sqrt(tfIdf.Select(x => x.Value).Select(x => Math.Pow(x, 2)).Sum());

            //Документы в которых имеется одно слово
            var indexDocuments = new List <int>();

            foreach (var item in words)
            {
                if (invertDict.ContainsKey(item))
                {
                    indexDocuments.AddRange(invertDict[item]);
                }
            }
            indexDocuments = indexDocuments.Distinct().ToList();

            //
            var docsLenght = new Dictionary <int, double>();

            //вычисляем длину документов
            foreach (var index in indexDocuments)
            {
                docsLenght.Add(index, Math.Sqrt(wordMatrix[index].Values.Select(x => Math.Pow(x, 2)).Sum()));
            }

            //косинусное сходство
            var result = new Dictionary <int, double>();

            foreach (var index in indexDocuments)
            {
                double fstPart = 0;
                foreach (var word in words)
                {
                    if (wordMatrix[index].ContainsKey(word))
                    {
                        //вектор на матрицу
                        fstPart += tfIdf[word] * wordMatrix[index][word];
                        if (index == 7)
                        {
                            Console.Write($"a:{tfIdf[word]} * b:{wordMatrix[index][word]} + ");
                        }
                    }
                }

                if (index == 7)
                {
                    Console.WriteLine($"\n{fstPart}/{docsLenght[index] * queryLenght}");
                    Console.WriteLine($"{docsLenght[index]} * {queryLenght}");
                }



                var point = (fstPart / (docsLenght[index] * queryLenght));
                //Console.WriteLine($"index:{index}, top:{fstPart}/{docsLenght[index] * queryLenght}");
                if (point == double.NaN)
                {
                    //если в запросе нет слов которые определяют какой-то документ(слова имеются во всех документых)
                    point = 0;
                }
                result.Add(index, point);
            }

            foreach (var item in result.OrderByDescending(x => x.Value).Take(10))
            {
                Console.WriteLine($"{item.Key} : {item.Value}");
            }
            Console.WriteLine();
        }
Beispiel #8
0
    public void SearchWord(string query)
    {
        var countDocument = 100;
        var porter        = new Porter();
        var words         = query.Split(' ').Select(x => porter.Stemm(x)).ToArray();
        var length        = words.Length;
        var tfs           = new double[length];

        for (int i = 0; i < length; i++)
        {
            var count = words.Where(x => x == words[i]).Count();
            tfs[i] = (double)count / length;
        }

        var idfs = new double[length];

        for (int i = 0; i < length; i++)
        {
            if (invertDict.ContainsKey(words[i]))
            {
                idfs[i] = invertDict.ContainsKey(words[i]) ? Math.Round(Math.Log10(countDocument / invertDict[words[i]].Count), 5) : 0;
            }
            else
            {
                idfs[i] = 0;
            }
        }

        var tfIdf = new Dictionary <string, double>();

        for (int i = 0; i < length; i++)
        {
            tfIdf.Add(words[i], tfs[i] * idfs[i]);
        }
        var queryLenght = Math.Sqrt(tfIdf.Select(x => x.Value).Select(x => Math.Pow(x, 2)).Sum());

        var indexDocuments = new List <int>();

        foreach (var item in words)
        {
            if (invertDict.ContainsKey(item))
            {
                indexDocuments.AddRange(invertDict[item]);
            }
        }
        indexDocuments = indexDocuments.Distinct().ToList();

        var docsLenght = new Dictionary <int, double>();

        foreach (var index in indexDocuments)
        {
            docsLenght.Add(index, Math.Sqrt(wordMatrix[index].Values.Select(x => Math.Pow(x, 2)).Sum()));
        }

        //cosinus similyarity
        var result = new Dictionary <int, double>();

        foreach (var index in indexDocuments)
        {
            double fstPart = 0;
            foreach (var word in words)
            {
                if (wordMatrix[index].ContainsKey(word))
                {
                    fstPart += tfIdf[word] * wordMatrix[index][word];
                }
            }
            var point = (fstPart / (docsLenght[index] * queryLenght));
            if (point == double.NaN)
            {
                point = 0;
            }
            result.Add(index, point);
        }

        foreach (var item in result.OrderByDescending(x => x.Value).Take(10))
        {
            Console.WriteLine($"{item.Key} : {item.Value}");
        }
        Console.WriteLine();
    }