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