private void EnlargeArray() { Word[] tmp = new Word[capacity * 2]; Array.Copy(words, tmp, length); words = tmp; capacity *= 2; }
/// <summary> /// Добавляем в массив слов новое слово /// </summary> /// <param name="word">Слово</param> public void AddWord(Word word) { if (length >= capacity) { EnlargeArray(); } words[length] = word; length++; }
/// <summary> /// Идетифицирует слово определяе имя это, или фамилия, или отчество /// - <b>N</b> - имя /// - <b>S</b> - фамилия /// - <b>F</b> - отчество /// @param NCLNameCaseWord word обьект класса слов, который необходимо идентифицировать /// </summary> protected override void DetectNamePart(Word word) { String name = word.Name; int length = name.Length; SetWorkingWord(name); //Считаем вероятность float first = 0; float second = 0; float father = 0; //если смахивает на отчество if (In(Last(3), new String [] {"вна", "чна", "вич", "ьич"})) { father+=3; } if (In(Last(2), new String [] {"ша"})) { first+=0.5f; } // буквы на которые никогда не закнчиваются имена if (In(Last(1), "еёжхцочшщъыэю")) { second += 0.3f; } // Используем массив характерных окончаний if (In(Last(2, 1), vowels+consonant)) { if (!In(Last(1), splitSecondExclude[Last(2, 1)])) { second += 0.4f; } } // Сохкращенные ласкательные имена типя Аня Галя и.т.д. if (Last(1) == "я" && In(Last(3, 1), vowels)) { first += 0.5f; } // Не бывает имет с такими предпоследними буквами if (In(Last(2, 1), "жчщъэю")) { second += 0.3f; } // Слова на мягкий знак. Существует очень мало имен на мягкий знак. Все остальное фамилии if (Last(1) == "ь") { // Имена типа нинЕЛь адЕЛь асЕЛь if (Last(3, 2) == "ел") { first += 0.7f; } // Просто исключения else if (InNames(name, new String [] {"лазарь", "игорь", "любовь"})) { first += 10; } // Если не то и не другое, тогда фамилия else { second += 0.3f; } } // Если две последних букв согласные то скорее всего это фамилия else if (In(Last(1), consonant + "ь") && In(Last(2, 1), consonant + "ь")) { // Практически все кроме тех которые оканчиваются на следующие буквы if (!In(Last(2), new String [] {"др", "кт", "лл", "пп", "рд", "рк", "рп", "рт", "тр"})) { second += 0.25f; } } // Слова, которые заканчиваются на тин if (Last(3) == "тин" && In(Last(4, 1), "нст")) { first += 0.5f; } //Исключения if (InNames(name, new String [] {"лев", "яков", "маша", "ольга", "еремей", "исак", "исаак", "ева", "ирина", "элькин", "мерлин"})) { first+=10; } // Фамилии которые заканчиваются на -ли кроме тех что типа натАли и.т.д. if (Last(2) == "ли" && Last(3, 1) != "а") { second+=0.4f; } // Фамилии на -як кроме тех что типа Касьян Куприян + Ян и.т.д. if (Last(2) == "ян" && length > 2 && !In(Last(3, 1), "ьи")) { second+=0.4f; } // Фамилии на -ур кроме имен Артур Тимур if (Last(2) == "ур") { if (!InNames(name, new String [] {"артур", "тимур"})) { second += 0.4f; } } // Разбор ласкательных имен на -ик if (Last(2) == "ик") { // Ласкательные буквы перед ик if (In(Last(3, 1), "лшхд")) { first += 0.3f; } else { second += 0.4f; } } // Разбор имен и фамилий, который заканчиваются на ина if (Last(3) == "ина") { // Все похожие на Катерина и Кристина if (In(Last(7), new String [] {"атерина", "ристина"})) { first+=10; } // Исключения else if (InNames(name, new String [] {"мальвина", "антонина", "альбина", "агриппина", "фаина", "карина", "марина", "валентина", "калина", "аделина", "алина", "ангелина", "галина", "каролина", "павлина", "полина", "элина", "мина", "нина"})) { first+=10; } // Иначе фамилия else { second += 0.4f; } } // Имена типа Николай if (Last(4) == "олай") { first += 0.6f; } // Фамильные окончания if (In(Last(2), new String [] {"ов", "ин", "ев", "ёв", "ый", "ын", "ой", "ук", "як", "ца", "ун", "ок", "ая", "га", "ёк", "ив", "ус", "ак", "яр", "уз", "ах", "ай"})) { second+=0.4f; } if (In(Last(3), new String [] {"ова", "ева", "ёва", "ына", "шен", "мей", "вка", "шир", "бан", "чий", "кий", "бей", "чан", "ган", "ким", "кан", "мар"})) { second+=0.4f; } if (In(Last(4), new String [] {"шена"})) { second+=0.4f; } float max = Math.Max(Math.Max(first, second), father); if (first == max) { word.NamePart = NamePart.FirstName; } else if (second == max) { word.NamePart = NamePart.SecondName; } else { word.NamePart = NamePart.FatherName; } }
/// <summary> /// Определение пола по правилам отчеств /// @param NCLNameCaseWord word обьект класса слов, для которого нужно определить пол /// </summary> protected override void GenderByFatherName(Word word) { SetWorkingWord(word.Name); if (Last(2) == "ич") { word.GenderProbability = new GenderProbability(10, 0); // мужчина } if (Last(2) == "на") { word.GenderProbability = new GenderProbability(0, 12); // женщина } }
/// <summary> /// Определение пола по правилам фамилий /// @param NCLNameCaseWord word обьект класса слов, для которого нужно определить пол /// </summary> protected override void GenderBySecondName(Word word) { SetWorkingWord(word.Name); GenderProbability prob = new GenderProbability(); if (In(Last(2), new String [] {"ов", "ин", "ев", "ий", "ёв", "ый", "ын", "ой"})) { prob.Man+=0.4f; } if (In(Last(3), new String [] {"ова", "ина", "ева", "ёва", "ына", "мин"})) { prob.Woman+=0.4f; } if (In(Last(2), new String [] {"ая"})) { prob.Woman+=0.4f; } word.GenderProbability = prob; }
/// <summary> /// Определение пола по правилам имен /// @param NCLNameCaseWord word обьект класса слов, для которого нужно определить пол /// </summary> protected override void GenderByFirstName(Word word) { SetWorkingWord(word.Name); GenderProbability prob = new GenderProbability(); //Попробуем выжать максимум из имени //Если имя заканчивается на й, то скорее всего мужчина if (Last(1) == "й") { prob.Man+=0.9f; } if (In(Last(2), new String [] {"он", "ов", "ав", "ам", "ол", "ан", "рд", "мп"})) { prob.Man+=0.3f; } if (In(Last(1), consonant)) { prob.Man+=0.01f; } if (Last(1) == "ь") { prob.Man+=0.02f; } if (In(Last(2), new String [] {"вь", "фь", "ль"})) { prob.Woman+=0.1f; } if (In(Last(2), new String [] {"ла"})) { prob.Woman+=0.04f; } if (In(Last(2), new String [] {"то", "ма"})) { prob.Man+=0.01f; } if (In(Last(3), new String [] {"лья", "вва", "ока", "ука", "ита"})) { prob.Man+=0.2f; } if (In(Last(3), new String [] {"има"})) { prob.Woman+=0.15f; } if (In(Last(3), new String [] {"лия", "ния", "сия", "дра", "лла", "кла", "опа"})) { prob.Woman+=0.5f; } if (In(Last(4), new String [] {"льда", "фира", "нина", "лита", "алья"})) { prob.Woman+=0.5f; } word.GenderProbability = prob; }
/// <summary> /// Ідентифікує слово визначаючи чи це ім’я, чи це прізвище, чи це побатькові /// <param name="word">Слово</param> /// </summary> protected override void DetectNamePart(Word word) { String namepart = word.Name; SetWorkingWord(namepart); //Считаем вероятность float first = 0; float second = 0; float father = 0; //если смахивает на отчество if (In(Last(3), new String[] {"вна", "чна", "ліч"}) || In(Last(4), new String[] {"ьмич", "ович"})) { father+=3; } //Похоже на имя if (In(Last(3), new String[] {"тин"}) || In(Last(4), new String[] {"ьмич", "юбов", "івна", "явка", "орив", "кіян"})) { first+=0.5f; } //Исключения if (InNames(namepart, new String[] {"лев", "гаїна", "афіна", "антоніна", "ангеліна", "альвіна", "альбіна", "аліна", "павло", "олесь", "микола", "мая", "англеліна", "елькін", "мерлін"})) { first+=10; } //похоже на фамилию if (In(Last(2), new String[] {"ов", "ін", "ев", "єв", "ий", "ин", "ой", "ко", "ук", "як", "ца", "их", "ик", "ун", "ок", "ша", "ая", "га", "єк", "аш", "ив", "юк", "ус", "це", "ак", "бр", "яр", "іл", "ів", "ич", "сь", "ей", "нс", "яс", "ер", "ай", "ян", "ах", "ць", "ющ", "іс", "ач", "уб", "ох", "юх", "ут", "ча", "ул", "вк", "зь", "уц", "їн", "де", "уз", "юр", "ік", "іч", "ро" })) { second+=0.4f; } if (In(Last(3), new String[] {"ова", "ева", "єва", "тих", "рик", "вач", "аха", "шен", "мей", "арь", "вка", "шир", "бан", "чий", "іна", "їна", "ька", "ань", "ива", "аль", "ура", "ран", "ало", "ола", "кур", "оба", "оль", "нта", "зій", "ґан", "іло", "шта", "юпа", "рна", "бла", "еїн", "има", "мар", "кар", "оха", "чур", "ниш", "ета", "тна", "зур", "нір", "йма", "орж", "рба", "іла", "лас", "дід", "роз", "аба", "чан", "ган"})) { second+=0.4f; } if (In(Last(4), new String[] {"ьник", "нчук", "тник", "кирь", "ский", "шена", "шина", "вина", "нина", "гана", "гана", "хній", "зюба", "орош", "орон", "сило", "руба", "лест", "мара", "обка", "рока", "сика", "одна", "нчар", "вата", "ндар", "грій"})) { second+=0.4f; } if (Last(1) == "і") { second+=0.2f; } float max = Math.Max(Math.Max(first, second), father); if (first == max) { word.NamePart = NamePart.FirstName; } else if (second == max) { word.NamePart = NamePart.SecondName; } else { word.NamePart = NamePart.FatherName; } }
/// <summary> /// Визначення статі, за правилами імені /// <param name="word">Слово</param> /// </summary> protected override void GenderByFirstName(Word word) { SetWorkingWord(word.Name); GenderProbability prob = new GenderProbability(); //Попробуем выжать максимум из имени //Если имя заканчивается на й, то скорее всего мужчина if (Last(1) == "й") { prob.Man+=0.9f; } if (InNames(workingWord, new String[] {"петро", "микола"})) { prob.Man+=30; } if (In(Last(2), new String[] {"он", "ов", "ав", "ам", "ол", "ан", "рд", "мп", "ко", "ло"})) { prob.Man+=0.5f; } if (In(Last(3), new String[] {"бов", "нка", "яра", "ила", "опа"})) { prob.Woman+=0.5f; } if (In(Last(1), consonant)) { prob.Man+=0.01f; } if (Last(1) == "ь") { prob.Man+=0.02f; } if (In(Last(2), new String[] {"дь"})) { prob.Woman+=0.1f; } if (In(Last(3), new String[] {"ель", "бов"})) { prob.Woman+=0.4f; } word.GenderProbability = prob; }
/// <summary> /// Склоняет слово по нужным правилам /// </summary> /// <param name="word">Слово</param> protected void WordCase(Word word) { Gender gender = word.Gender; String genderName = (gender == Gender.Man ? "Man" : "Woman"); String namePartName = ""; switch (word.NamePart) { case NamePart.FirstName: namePartName = "First"; break; case NamePart.SecondName: namePartName = "Second"; break; case NamePart.FatherName: namePartName = "Father"; break; } String methodName = genderName + namePartName + "Name"; SetWorkingWord(word.Name); bool res = (bool)this.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance).Invoke(this, null); if (res) { word.NameCases = lastResult; word.Rule = lastRule; } else { MakeResultTheSame(); word.NameCases = lastResult; word.Rule = -1; } }
/// <summary> /// Предварительно определяет пол во слове /// </summary> /// <param name="word">Слово для определения</param> private void PrepareGender(Word word) { if (!word.isGenderSolved()) { switch (word.NamePart) { case NamePart.FirstName: GenderByFirstName(word); break; case NamePart.SecondName: GenderBySecondName(word); break; case NamePart.FatherName: GenderByFatherName(word); break; } } }
/// <summary> /// Идентификирует нужное слово /// </summary> /// <param name="word">Слово</param> private void PrepareNamePart(Word word) { if (word.NamePart == NamePart.Null) { DetectNamePart(word); } }
/// <summary> /// Установить отчество человека /// </summary> /// <param name="name">Отчество</param> /// <returns></returns> public Core SetFatherName(String name) { if (name.Trim() != "") { Word tmpWord = new Word(name); tmpWord.NamePart = NamePart.FatherName; words.AddWord(tmpWord); NotReady(); } return this; }
/// <summary> /// Идетифицирует слово определяе имя это, или фамилия, или отчество /// </summary> /// <param name="word">Слово для которое нужно идетифицировать</param> abstract protected void DetectNamePart(Word word);
/// <summary> /// Определяет пол человека по его отчеству /// </summary> /// <param name="word">Отчество</param> abstract protected void GenderByFatherName(Word word);
/// <summary> /// Определяет пол человека по его фамилии /// </summary> /// <param name="word">Фамилия</param> abstract protected void GenderBySecondName(Word word);
/// <summary> /// Определяет пол человека по его имени /// </summary> /// <param name="word">Имя</param> abstract protected void GenderByFirstName(Word word);