protected virtual CyrRule[] GetRules(NumbersEnum number, int wordPartIndex) { if (number == NumbersEnum.Singular) { return(new CyrRule[] { new CyrRule(string.Empty), this.rules[0 + wordPartIndex * rulesPerNoun], this.rules[1 + wordPartIndex * rulesPerNoun], this.rules[2 + wordPartIndex * rulesPerNoun], this.rules[3 + wordPartIndex * rulesPerNoun], this.rules[4 + wordPartIndex * rulesPerNoun] }); } else { return(new CyrRule[] { this.rules[5 + wordPartIndex * rulesPerNoun], this.rules[6 + wordPartIndex * rulesPerNoun], this.rules[7 + wordPartIndex * rulesPerNoun], this.rules[8 + wordPartIndex * rulesPerNoun], this.rules[9 + wordPartIndex * rulesPerNoun], this.rules[10 + wordPartIndex * rulesPerNoun] }); } }
public void SetName(string name, GendersEnum gender, CasesEnum @case, NumbersEnum number, AnimatesEnum animate) { CyrRule[] rules = this.GetRules(gender, number, animate); CyrRule rule = rules[(int)@case - 1]; this.Name = rule.Revert(this.Name, name); }
/// <summary> /// Поиск существительного по точному совпадению с автоматическим определением рода, падежа и числа. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Существительное в любом роде, числе и падеже.</param> /// <param name="number">Число найденного существительного.</param> /// <param name="case">Падеж найденного существительного.</param> /// <returns></returns> public CyrNoun GetOrDefault(string word, out CasesEnum @case, out NumbersEnum number) { DictionaryKey key; CyrNoun noun; // Существительные, без формы единственного числа, не имеют рода. К примеру "ворота" или "шахматы". GendersEnum[] gendersWithZero = new GendersEnum[] { GendersEnum.Masculine, GendersEnum.Feminine, GendersEnum.Neuter, GendersEnum.Undefined }; foreach (CasesEnum c in this.cases) { foreach (NumbersEnum n in this.numbers) { foreach (GendersEnum g in gendersWithZero) { key = new DictionaryKey(word, g, c, n); if (this.words.TryGetValue(key, out noun)) { @case = key.Case; number = key.Number; return(noun); } } } } @case = 0; number = 0; return(null); }
public DictionaryKey(string name, GendersEnum gender, CasesEnum @case, NumbersEnum number) { this.Name = name; this.Gender = gender; this.Case = @case; this.Number = number; }
protected virtual CyrRule[] GetRules(GendersEnum gender, NumbersEnum number, AnimatesEnum animate) { CyrRule[] rules; if (gender == GendersEnum.Masculine) { rules = new CyrRule[] { new CyrRule(string.Empty), this.rules[0], this.rules[1], animate == AnimatesEnum.Animated ? this.rules[2] : new CyrRule(string.Empty), this.rules[3], this.rules[4] }; } else if (gender == GendersEnum.Feminine) { rules = new CyrRule[] { this.rules[5], this.rules[6], this.rules[7], this.rules[8], this.rules[9], this.rules[10] }; } else if (gender == GendersEnum.Neuter) { rules = new CyrRule[] { this.rules[11], this.rules[12], this.rules[13], this.rules[14], this.rules[15], this.rules[16] }; } else if (number == NumbersEnum.Plural) { rules = new CyrRule[] { this.rules[17], this.rules[18], this.rules[19], animate == AnimatesEnum.Animated ? this.rules[20] : this.rules[17], this.rules[21], this.rules[22] }; } else { throw new InvalidOperationException($"Unable to decline adjective with Gender: [{gender}], Number: [{number}], Animate: [{animate}]."); } return(rules); }
private void btnDecline_Click(object sender, EventArgs e) { if (txtWord.Text.IsNullOrEmpty()) { MessageBox.Show("Необходимо ввести слово!"); } CyrAdjective adj; GendersEnum declineToGender = (GendersEnum)(ddlGender.SelectedIndex + 1); AnimatesEnum declineToAnimate = (AnimatesEnum)(ddlAnimate.SelectedIndex + 1); NumbersEnum declineToNumber = (NumbersEnum)(ddlNumber.SelectedIndex + 1); string foundWord; GendersEnum foundGender; CasesEnum foundCase; NumbersEnum foundNumber; AnimatesEnum foundAnimate; CyrResult result = null; try { Stopwatch watch = new Stopwatch(); watch.Start(); adj = cyrCollection.Get(txtWord.Text, out foundWord, out foundGender, out foundCase, out foundNumber, out foundAnimate); if (declineToNumber == NumbersEnum.Singular) { result = adj.Decline(declineToGender, declineToAnimate); } else { result = adj.DeclinePlural(declineToAnimate); } watch.Stop(); this.Log($"Склонение слова {txtWord.Text} заняло {watch.Elapsed}."); } catch (CyrWordNotFoundException) { MessageBox.Show("Данное слово не найдено в коллекции!"); return; } this.SetResult(result); txtCollectionName.Text = foundWord; txtDetails.Text = $"{foundGender}, {foundCase}, {foundNumber}, {foundAnimate}"; if (txtWord.Text == foundWord) { txtCollectionName.BackColor = SystemColors.Control; } else { txtCollectionName.BackColor = SystemColors.Highlight; } }
/// <summary> /// Поиск существительного по точному совпадению с указанием рода, падежа и числа. /// Выбрасывает <see cref="CyrWordNotFoundException"/> если слово не было найдено. /// </summary> /// <param name="word">Существительное.</param> /// <param name="gender">Род, в котором указано существительного.</param> /// <param name="case">Падеж, в котором указано существительного.</param> /// <param name="number">Число, в котором указано существительного.</param> /// <returns></returns> public CyrNoun Get(string word, GendersEnum gender, CasesEnum @case, NumbersEnum number) { CyrNoun noun = this.GetOrDefault(word, gender, @case, number); if (noun == null) { throw new CyrWordNotFoundException(word, gender, @case, number, 0); } return(noun); }
/// <summary> /// Поиск прилагательного по точному совпадению с указанием рода, падежа, числа и одушевленности. /// Выбрасывает <see cref="CyrWordNotFoundException"/> если слово не было найдено. /// </summary> /// <param name="word">Прилагательное.</param> /// <param name="gender">Род, в котором указано прилагательное.</param> /// <param name="case">Падеж, в котором указано прилагательное.</param> /// <param name="number">Число, в котором указано прилагательное.</param> /// <param name="animate">Одушевленность прилагательного.</param> /// <returns></returns> public CyrAdjective Get(string word, GendersEnum gender, CasesEnum @case, NumbersEnum number, AnimatesEnum animate) { CyrAdjective adjective = this.GetOrDefault(word, gender, @case, number, animate); if (adjective == null) { throw new CyrWordNotFoundException(word, gender, @case, number, animate); } return(adjective); }
protected virtual string GetNumberStringRu(NumbersEnum number) { switch (number) { case NumbersEnum.Singular: return("единственное число"); case NumbersEnum.Plural: return("множественное число"); default: return(string.Empty); } }
/// <summary> /// Поиск существительного по неточному совпадению с автоматическим определением рода, падежа и числа. /// Выбрасывает <see cref="CyrWordNotFoundException"/> если слово не было найдено. /// </summary> /// <param name="word">Существительное в любом роде, числе и падеже.</param> /// <param name="foundWord">Существительное, найденное в словаре.</param> /// <param name="number">Число найденного существительного.</param> /// <param name="case">Падеж найденного существительного.</param> /// <returns></returns> public CyrNoun Get(string word, out string foundWord, out CasesEnum @case, out NumbersEnum number) { CyrNoun noun = this.GetOrDefault(word, out foundWord, out @case, out number); if (noun == null) { throw new CyrWordNotFoundException(word, 0, @case, number, 0); } return(noun); }
public void SetName(string name, CasesEnum @case, NumbersEnum number) { if (this.rules.Length > rulesPerNoun) { throw new NotImplementedException($"{nameof(SetName)} is not yet supported for composite nouns."); } CyrRule[] rules = this.GetRules(number, 0); CyrRule rule = rules[(int)@case - 1]; this.Name = rule.Revert(this.Name, name); }
protected CyrResult DeclineMultipleParts(string[] parts, NumbersEnum number) { List <CyrResult> results = new List <CyrResult>(); for (int i = 0; i < parts.Length; i++) { CyrRule[] rules = this.GetRules(number, i); CyrResult result = this.GetResult(parts[i], rules); results.Add(result); } return(this.JoinResults(results)); }
public NumberModel(NumbersEnum value) { this.Value = value; switch (value) { case NumbersEnum.Plural: this.Name = "Множественное число"; break; case NumbersEnum.Singular: this.Name = "Единственное число"; break; default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Поиск существительного по неточному совпадению с указанием рода, падежа и числа. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Существительное.</param> /// <param name="foundWord">Существительное, найденное в словаре.</param> /// <param name="gender">Род, в котором указано существительного.</param> /// <param name="case">Падеж, в котором указано существительного.</param> /// <param name="number">Число, в котором указано существительного.</param> /// <returns></returns> public CyrNoun GetOrDefault(string word, out string foundWord, GendersEnum gender, CasesEnum @case, NumbersEnum number) { CyrNoun noun = this.GetOrDefault(word, gender, @case, number); if (noun != null) { foundWord = word; return(new CyrNoun(noun)); } DictionaryKey key = default; foundWord = null; if (this.EnableCache) { key = new DictionaryKey(word, gender, @case, number); if (this.similarSearchByKeyCache.TryGetValue(key, out foundWord)) { noun = this.GetOrDefault(foundWord, gender, @case, number); noun = new CyrNoun(noun); noun.SetName(word, @case, number); return(noun); } } foreach (string candidate in this.cyrData.GetSimilars(word, this.wordCandidates, this.NounMinSameLetters, this.NounMaxSameLetters)) { noun = this.GetOrDefault(candidate, gender, @case, number); if (noun == null) { continue; } noun = new CyrNoun(noun); noun.SetName(word, @case, number); foundWord = candidate; break; } if (this.EnableCache) { this.similarSearchByKeyCache.Add(key, foundWord); } return(noun); }
/// <summary> /// Поиск существительного по точному совпадению. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Существительное.</param> /// <param name="gender">Род, в котором указано существительного.</param> /// <param name="case">Падеж, в котором указано существительного.</param> /// <param name="number">Число, в котором указано существительного.</param> /// <returns></returns> public CyrNoun GetOrDefault(string word, GendersEnum gender, CasesEnum @case, NumbersEnum number) { DictionaryKey key = new DictionaryKey(word, gender, @case, number); CyrNoun noun; if (this.words.TryGetValue(key, out noun)) { return(new CyrNoun(noun)); } return(null); }
/// <summary> /// Поиск существительного по неточному совпадению с автоматическим определением рода, падежа и числа. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Существительное в любом роде, числе и падеже.</param> /// <param name="foundWord">Существительное, найденное в словаре.</param> /// <param name="number">Число найденного существительного.</param> /// <param name="case">Падеж найденного существительного.</param> /// <returns></returns> public CyrNoun GetOrDefault(string word, out string foundWord, out CasesEnum @case, out NumbersEnum number) { CyrNoun noun = this.GetOrDefault(word, out @case, out number); if (noun != null) { foundWord = word; return(new CyrNoun(noun)); } foundWord = this.GetSimilar(word, this.NounMinSameLetters, this.NounMaxSameLetters); if (string.IsNullOrEmpty(foundWord)) { return(null); } noun = this.GetOrDefault(foundWord, out @case, out number); if (noun != null) { noun = new CyrNoun(noun); noun.SetName(word, @case, number); return(noun); } return(null); }
/// <summary> /// Поиск прилагательного по неточному совпадению с указанием рода, падежа, числа и одушевленности. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Прилагательное.</param> /// <param name="foundWord">Прилагательное, найденное в словаре.</param> /// <param name="gender">Род, в котором указано прилагательное.</param> /// <param name="case">Падеж, в котором указано прилагательное.</param> /// <param name="number">Число, в котором указано прилагательное.</param> /// <param name="animate">Одушевленность прилагательного.</param> /// <returns></returns> public CyrAdjective GetOrDefault(string word, out string foundWord, GendersEnum gender, CasesEnum @case, NumbersEnum number, AnimatesEnum animate) { CyrAdjective adjective = this.GetOrDefault(word, gender, @case, number, animate); if (adjective != null) { foundWord = word; return(new CyrAdjective(adjective)); } foundWord = this.GetSimilar(word, this.AdjectiveMinSameLetters, this.AdjectiveMaxSameLetters); if (string.IsNullOrEmpty(foundWord)) { return(null); } adjective = this.GetOrDefault(foundWord, gender, @case, number, animate); if (adjective != null) { adjective = new CyrAdjective(adjective); adjective.SetName(word, gender, @case, number, animate); return(adjective); } return(null); }
protected CyrResult Decline(string Phrase, GetConditionsEnum Condition, NumbersEnum Number) { if (Phrase.IsNullOrEmpty()) { return new CyrResult(); } List<object> words = new List<object>(); string[] parts = Phrase.Split(' ').Select(val => val.Trim()).Where(val => val.IsNotNullOrEmpty()).ToArray(); List<CyrResult> results = new List<CyrResult>(); foreach (string w in parts) { SpeechPartsEnum speech = this.DetermineSpeechPart(w); switch (speech) { case SpeechPartsEnum.Adjective: CyrAdjective adj = this.adjCollection.Get(w, Condition); words.Add(adj); break; case SpeechPartsEnum.Noun: CyrNoun noun = this.nouCollection.Get(w, Condition); words.Add(noun); break; default: throw new ArgumentException("This speech part is not supported yet. Speech part: " + speech.ToString()); } } for (int i = 0; i < words.Count; i++) { CyrNoun noun = words[i] as CyrNoun; if (noun != null) { if (Number == NumbersEnum.Plural) { results.Add(noun.DeclinePlural()); } else { results.Add(noun.Decline()); } continue; } CyrAdjective adj = words[i] as CyrAdjective; noun = this.GetNextPreviousNoun(words, i); if (Number == NumbersEnum.Plural) { if (noun != null) { results.Add(adj.DeclinePlural(noun.Animate)); } else { results.Add(adj.DeclinePlural(AnimatesEnum.Animated)); } } else { if (noun != null) { results.Add(adj.Decline(noun.Animate)); } else { results.Add(adj.Decline(AnimatesEnum.Animated)); } } } CyrResult result = results.First(); for (int i = 1; i < results.Count; i++) { result = result + results[i]; } return result; }
public CyrWordNotFoundException(string word, GendersEnum gender, CasesEnum @case, NumbersEnum number, AnimatesEnum animate) : base($"The word was not found in the collection. Word: [{word}], gender: [{gender}], case: [{@case}], number: [{number}], animte: [{animate}].") { this.Word = word; this.Gender = gender; this.Case = @case; this.Number = number; this.Animate = animate; }
/// <summary> /// Поиск прилагательного по точному совпадению с указанием рода, падежа, числа и одушевленности. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Прилагательное.</param> /// <param name="gender">Род, в котором указано прилагательное.</param> /// <param name="case">Падеж, в котором указано прилагательное.</param> /// <param name="number">Число, в котором указано прилагательное.</param> /// <param name="animate">Одушевленность прилагательного.</param> /// <returns></returns> public CyrAdjective GetOrDefault(string word, GendersEnum gender, CasesEnum @case, NumbersEnum number, AnimatesEnum animate) { DictionaryKey key = new DictionaryKey(word, gender, @case, number, animate); CyrAdjective adjective; if (this.words.TryGetValue(key, out adjective)) { return(new CyrAdjective(adjective)); } return(null); }
protected CyrResult Decline(string Phrase, GetConditionsEnum Condition, NumbersEnum Number) { if (Phrase.IsNullOrEmpty()) { return(new CyrResult()); } List <object> words = new List <object>(); string[] parts = Phrase.Split(' ').Select(val => val.Trim()).Where(val => val.IsNotNullOrEmpty()).ToArray(); List <CyrResult> results = new List <CyrResult>(); foreach (string w in parts) { SpeechPartsEnum speech = this.DetermineSpeechPart(w); switch (speech) { case SpeechPartsEnum.Adjective: CyrAdjective adj = this.adjCollection.Get(w, Condition); words.Add(adj); break; case SpeechPartsEnum.Noun: CyrNoun noun = this.nounCollection.Get(w, Condition); words.Add(noun); break; default: throw new ArgumentException("This speech part is not supported yet. Speech part: " + speech.ToString()); } } for (int i = 0; i < words.Count; i++) { CyrNoun noun = words[i] as CyrNoun; if (noun != null) { if (Number == NumbersEnum.Plural) { results.Add(noun.DeclinePlural()); } else { results.Add(noun.Decline()); } continue; } CyrAdjective adj = words[i] as CyrAdjective; noun = this.GetNextPreviousNoun(words, i); if (Number == NumbersEnum.Plural) { if (noun != null) { results.Add(adj.DeclinePlural(noun.Animate)); } else { results.Add(adj.DeclinePlural(AnimatesEnum.Animated)); } } else { if (noun != null) { results.Add(adj.Decline(noun.Animate)); } else { results.Add(adj.Decline(AnimatesEnum.Animated)); } } } CyrResult result = results.First(); for (int i = 1; i < results.Count; i++) { result = result + results[i]; } return(result); }
public void Decline() { this.InputText = this.inputText?.Trim(); if (string.IsNullOrEmpty(this.InputText)) { return; } CyrAdjective adj = null; string foundWord = null; GendersEnum foundGender = GendersEnum.Undefined; CasesEnum foundCase = CasesEnum.Nominative; string foundCaseName = null; NumbersEnum foundNumber = NumbersEnum.Singular; AnimatesEnum foundAnimate = AnimatesEnum.Animated; if (this.IsStrictSearch && !this.IsManualPropertiesInput) { adj = this.CyrAdjectiveCollection.GetOrDefault(this.InputText, out foundGender, out foundCase, out foundNumber, out foundAnimate); } else if (!this.IsStrictSearch && !this.IsManualPropertiesInput) { adj = this.CyrAdjectiveCollection.GetOrDefault(this.InputText, out foundWord, out foundGender, out foundCase, out foundNumber, out foundAnimate); } else if (this.IsStrictSearch && this.IsManualPropertiesInput) { foundGender = InputGender.Value; foundCase = InputCase.Value; foundNumber = InputNumber.Value; foundAnimate = InputAnimate.Value; adj = this.CyrAdjectiveCollection.GetOrDefault(this.InputText, foundGender, foundCase, foundNumber, foundAnimate); } else if (!this.IsStrictSearch && this.IsManualPropertiesInput) { foundGender = InputGender.Value; foundCase = InputCase.Value; foundNumber = InputNumber.Value; foundAnimate = InputAnimate.Value; adj = this.CyrAdjectiveCollection.GetOrDefault(this.InputText, out foundWord, foundGender, foundCase, foundNumber, foundAnimate); } this.DeclineResult = new List <AdjectiveDeclineResultRowModel>(); this.WordProperties = new List <KeyValuePair <string, string> >(); this.RaisePropertyChanged(nameof(DeclineResult)); this.RaisePropertyChanged(nameof(WordProperties)); if (adj == null) { this.IsDeclineResultVisible = false; this.SearchResultTitle = $"По запросу \"{this.InputText}\" ничего не найдено"; return; } Dictionary <KeyValuePair <GendersEnum, AnimatesEnum>, CyrResult> results = new System.Collections.Generic.Dictionary <KeyValuePair <GendersEnum, AnimatesEnum>, CyrResult>(); foreach (GenderModel gender in this.Genders) { foreach (AnimateModel animate in this.Animates) { KeyValuePair <GendersEnum, AnimatesEnum> key = new KeyValuePair <GendersEnum, AnimatesEnum>(gender.Value, animate.Value); CyrResult value; if (gender.Value == GendersEnum.Undefined) { value = adj.DeclinePlural(animate.Value); } else { value = adj.Decline(gender.Value, animate.Value); } results.Add(key, value); } } foreach (CyrDeclineCase @case in CyrDeclineCase.GetEnumerable()) { if (@case.Value == foundCase) { foundCaseName = @case.NameRu; } AdjectiveDeclineResultRowModel row = new AdjectiveDeclineResultRowModel() { CaseName = @case.NameRu, CaseDescription = @case.Description }; row.SingularMasculineAnimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Masculine, AnimatesEnum.Animated)].Get(@case.Value); row.SingularFeminineAnimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Feminine, AnimatesEnum.Animated)].Get(@case.Value); row.SingularNeuterAnimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Neuter, AnimatesEnum.Animated)].Get(@case.Value); row.SingularMasculineInanimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Masculine, AnimatesEnum.Inanimated)].Get(@case.Value); row.SingularFeminineInanimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Feminine, AnimatesEnum.Inanimated)].Get(@case.Value); row.SingularNeuterInanimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Neuter, AnimatesEnum.Inanimated)].Get(@case.Value); row.PluralAnimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Undefined, AnimatesEnum.Animated)].Get(@case.Value); row.PluralInanimate = results[new KeyValuePair <GendersEnum, AnimatesEnum>(GendersEnum.Undefined, AnimatesEnum.Inanimated)].Get(@case.Value); this.DeclineResult.Add(row); } this.WordProperties.Add(new KeyValuePair <string, string>("Слово в словаре", foundWord)); this.WordProperties.Add(new KeyValuePair <string, string>("Род", new GenderModel(foundGender).Name)); this.WordProperties.Add(new KeyValuePair <string, string>("Падеж", foundCaseName)); this.WordProperties.Add(new KeyValuePair <string, string>("Число", new NumberModel(foundNumber).Name)); this.WordProperties.Add(new KeyValuePair <string, string>("Одушевленность", new AnimateModel(foundAnimate).Name)); this.IsDeclineResultVisible = true; this.SearchResultTitle = $"Результат поиска по запросу \"{this.InputText}\""; }
public IActionResult WithEnumParam(NumbersEnum numbers) { return(null); }
/// <summary> /// Поиск прилагательного по точному совпадению с автоматическим определением рода, падежа, числа и одушевленности. /// Возвращает null если слово не было найдено. /// </summary> /// <param name="word">Прилагательное в любом роде, числе и падеже.</param> /// <param name="gender">Род найденного прилагательного.</param> /// <param name="number">Число найденного прилагательного.</param> /// <param name="case">Падеж найденного прилагательного.</param> /// <returns></returns> public CyrAdjective GetOrDefault(string word, out GendersEnum gender, out CasesEnum @case, out NumbersEnum number, out AnimatesEnum animate) { DictionaryKey key; CyrAdjective adjective; foreach (AnimatesEnum a in this.animates) { foreach (GendersEnum g in this.genders) { foreach (CasesEnum c in this.cases) { key = new DictionaryKey(word, g, c, NumbersEnum.Singular, a); if (this.words.TryGetValue(key, out adjective)) { gender = key.Gender; @case = key.Case; number = key.Number; animate = key.Animate; return(adjective); } } } foreach (CasesEnum c in this.cases) { key = new DictionaryKey(word, 0, c, NumbersEnum.Plural, a); if (this.words.TryGetValue(key, out adjective)) { gender = key.Gender; @case = key.Case; number = key.Number; animate = key.Animate; return(adjective); } } } gender = 0; @case = 0; number = 0; animate = 0; return(null); }