public static List <TransliterationRule> Recognize(
            Language sourceLanguage,
            Language resultLanguage,
            IEnumerable <WordInLangs> wordTextTranslations)
        {
            var wordGraphemeTranslations = (
                from t in wordTextTranslations
                let match = WordMatch.Create(t.Lang1Word, t.Lang2Word, sourceLanguage, resultLanguage)
                            where match.Success
                            select GraphemeTranslation.Create(match.LetterMatches, sourceLanguage.ToGraphemes(t.Lang1Word))
                ).ToList();

            var correctedGraphemeTranslations =
                RuleRecognizer.CorrectGraphemeLengths(sourceLanguage, wordGraphemeTranslations);

            var allGraphemeTranslations = Db.EngToRusMap
                                          .Select(x => new GraphemeTranslation(sourceLanguage.ToGrapheme(x.eng.ToString()), x.rus))
                                          .Union(correctedGraphemeTranslations);

            var rules =
                RuleRecognizer.CreateTranslationRules(allGraphemeTranslations);

            return(rules);
        }
Exemple #2
0
        /// <summary>
        ///     Объединить графемы, если есть такая возможность
        /// </summary>
        /// <param name="translations"></param>
        /// <returns></returns>
        public IEnumerable <GraphemeTranslation> Correct(IReadOnlyList <GraphemeTranslation> translations)
        {
            // Берём графемы и пробуем с ними пройти по дереву букв/графем.
            // Возвращяем наидлиннейший путь который смогли пройти.
            GraphemeVariant?    variant           = this.root;
            GraphemeTranslation mergedTranslation = new();
            int savedTranslationNum = 0;
            GraphemeTranslation?savedMergedTranslation = null;
            bool savedButNotReturned = false;

            for (int translationNum = 0; translationNum < translations.Count; translationNum++)
            {
                GraphemeTranslation nextTranslation = translations[translationNum];

                string letters = nextTranslation.Original.Letters;
                mergedTranslation.MergeWith(nextTranslation);

                for (int letterNum = 0; letterNum < letters.Length; letterNum++)
                {
                    // Если дальше проходить по дереву графем нельзя - возвращяем последнее успешное
                    if (variant?.Variants == null)
                    {
                        Load();
                        if (savedMergedTranslation != null)
                        {
                            yield return(savedMergedTranslation);
                        }

                        savedButNotReturned = false;
                        break;
                    }

                    // Делаем следующий шаг по дереву графем
                    char letter = letters[letterNum];
                    variant = variant.Variants[letter - this.offset];

                    // Если дальше проходить по дереву графем нельзя - возвращяем последнее успешное
                    if (variant == null)
                    {
                        Load();
                        if (savedMergedTranslation != null)
                        {
                            yield return(savedMergedTranslation);
                        }

                        savedButNotReturned = false;
                        break;
                    }

                    // Нашли успешное объединение - сохраняем
                    if (letterNum == letters.Length - 1 && variant.ExistGrapheme)
                    {
                        Save();
                        savedButNotReturned = true;
                    }
                }

                // Сохраняем успешное объединение графем
                void Save()
                {
                    savedTranslationNum    = translationNum;
                    savedMergedTranslation = mergedTranslation.Clone();
                }

                // Возвращяем сохранённое успешное объединение графем
                void Load()
                {
                    translationNum    = savedTranslationNum;
                    variant           = this.root;
                    mergedTranslation = new GraphemeTranslation();
                }
            }

            // Если есть успешное объединение графем которое не вернули - возвращяем
            if (savedButNotReturned && savedMergedTranslation != null)
            {
                yield return(savedMergedTranslation);
            }
        }