Доброго времечка, господа!
Есть ли у кого готовый алгоритм склонения по падежам
Фамилии Имени Отчества?
Не требуется абсолютной точности, потому что понятно, что придется подключать 100 Кб словарь исключений.
Предполагается, что будет осуществляться визуальный контроль результатов.
Склонение ФИО по падежам
Я не вижу тут трудностей...например, такой код:
ПыЗы:
Borland C++ Builder
Всего и делов...А вот как программа работает:
Программа выведет следующее:
Панасенку Олександру Олександровичу
Всего и делов...
ПыЗы:
Borland C++ Builder
Код: Выделить всё
#define davatelniy 0x10
char* Padezh(char* slovo,char* okon,int pad)
{
AnsiString str = new AnsiString (slovo);
str.Delete(str.Pos(okon),str.Length);
switch (pad)
{
....
case 0x10:
{
str+= "у";
break;
}
default:
throw Exception("Unknown падеж :) ");
....
}
return str.c_str();
}
Код: Выделить всё
char sur_name [15] = "Панасенко";
char name[15] = "Олександр"
char po_batkovi[15] = "Олександрович";
char a[15],b[15],c[15];
strcat (a,padezh(sur_name));
strcat (b,padezh(name));
strcat (c,padezh(po_batkovi));
ShowMessage(AnsiString(a)+"\t"+AnsiString(b)+"\t"+AnsiString(c));
Панасенку Олександру Олександровичу
Всего и делов...
-
- Сообщения: 492
- Зарегистрирован: 17 фев 2004, 11:26
- Откуда: Ленинград (который Город на Неве)
- Контактная информация:
Особенно хорошо должны при таком раскладе склоняться фамилии, например
Сухих или Ли. Вот здорово-то?
Сухиху и Лиу.
Сухих или Ли. Вот здорово-то?
Сухиху и Лиу.
"Особое внимание начинающих аквариумистов хотим обратить на то, что рыбки никогда не спят на спинке!" (c)
viel spass, DeeJayC
viel spass, DeeJayC
-
- Сообщения: 9
- Зарегистрирован: 16 авг 2004, 15:39
- Откуда: Saint-Petersburg
- Контактная информация:
Спасибо. Трудности как раз не в алгоритме, а найти уже готовые исходики.
Недавно нашел исходики, написанные для 1C и на скороую руку набрасал функции, эмулирующие 1C.
Просьба не ругать, времени не было разбирать исходный код на 1C, который был просто ужасен для чтения;(
Пример использования
Cpadej oPadej;
oPadej.Padej( "Иванов Петр Алексеевич",2, 1));
oPadej.Padej( "Аликперова Нигель Амбросьевна",2, 2));
Недавно нашел исходики, написанные для 1C и на скороую руку набрасал функции, эмулирующие 1C.
Просьба не ругать, времени не было разбирать исходный код на 1C, который был просто ужасен для чтения;(
Код: Выделить всё
/////////////////////////////////////////////////////////////////////////////
#define C(c, f, s ) ((c) ? (f):(s) )
//------------------------------------------------------------------
class CPadej
{
public:
CPadej::CPadej() { Clear(); }
virtual CPadej::~CPadej() { Clear();}
void Clear();
CString& Left(const char* sz0, int nCount);
CString& Trim(const char* sz0);
CString& Right(const char* sz0, int nCount);
CString& Mid(const char* sz0, int iFirst);
CString& Mid(const char* sz0, int iFirst, int nCount);
CString& TrimRight(const char* sz0);
CString& ToLow(const char* sz0);
CString& ToUpper(const char* sz0);
CString& Replace(const char* sz, const char* sz0, const char* sz1);
CString& New(const char* sz);
CString& PadejWord(CString& z1, int z2 = 2, const char* z3="*", int z4=0);
const char* Padej(CString& z1, int z2=2, int z3=3, CString z4="123", int z5=1);
protected:
std::vector <CString*> _vStr;
};
//------------------------------------------------------------------
inline int Find(const char* sz0, const char* sz1)
{
char* p = strstr(sz0, sz1);
if (!p)
return 0;
else
return p - sz0 + 1;
}
//------------------------------------------------------------------
void CPadej::Clear()
{
for (size_t i=0; i< _vStr.size(); i++)
{
delete _vStr[i];
_vStr[i] = NULL;
}
_vStr.clear();
}
//------------------------------------------------------------------
CString& CPadej::Left(const char* sz0, int nCount)
{
CString str = sz0;
if (nCount > str.GetLength())
nCount = str.GetLength();
else if (nCount < 0)
nCount = 0;
CString* p = new CString();
*p = str.Left(nCount);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::Trim(const char* sz0)
{
CString str = sz0;
CString* p = new CString();
*p = str.Trim();
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::Right(const char* sz0, int nCount)
{
CString str = sz0;
if (nCount > str.GetLength())
nCount = str.GetLength();
else if (nCount < 0)
nCount = 0;
CString* p = new CString();
*p = str.Right(nCount);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::Mid(const char* sz0, int iFirst, int nCount)
{
CString str = sz0;
if ((iFirst-1) > str.GetLength())
iFirst = str.GetLength()+1;
else if ((iFirst-1) < 0)
iFirst = 1;
CString* p = new CString();
*p = str.Mid(iFirst-1, nCount);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::Mid(const char* sz0, int iFirst)
{
CString str = sz0;
if ((iFirst-1) > str.GetLength())
iFirst = str.GetLength()+1;
else if ((iFirst-1) < 0)
iFirst = 1;
CString* p = new CString();
*p = str.Mid(iFirst-1);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::TrimRight(const char* sz0)
{
CString str = sz0;
CString* p = new CString();
*p = str.TrimRight();
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::ToLow(const char* sz0)
{
CString* p = new CString();
*p = sz0;
_strlwr((char*)(LPCTSTR)*p);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::ToUpper(const char* sz0)
{
CString* p = new CString();
*p = sz0;
_strupr((char*)(LPCTSTR)*p);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::Replace(const char* sz, const char* sz0, const char* sz1)
{
CString* p = new CString();
*p = sz;
p->Replace(sz0, sz1);
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//------------------------------------------------------------------
CString& CPadej::New(const char* sz)
{
CString* p = new CString();
*p = sz;
_vStr.push_back(p);
return *_vStr[ _vStr.size()-1 ];
}
//
// SuperJur.Narod.Ru
// Функция для склонения одного слова!!!
// z1 - само слово
// z2 - номер падежа
// z3 - пол
// z4 - 1-склонять как фамилию, 2-имя, 3-отчество
CString& CPadej::PadejWord(CString& z1, int z2, const char* z3, int z4)
{
int z5, za, zb, zc, zd, ze;
const char *z6, *z7, *z8, *z9;
CString str, str1, str2, str3, str4, str5, str6, str7;
CString str10, zf;
z5=Find(z1,"-");
str10 = "-";
z6=C(z5==0,"",str10 + PadejWord(Mid(z1,z5+1,strlen(z1)-z5+1),z2,z3,z4));
z1=ToLow(C(z5==0,z1,Left(z1,z5-1)));
z7=Right(z1,3);
z8=Right(z7,2);
z9=Right(z8,1);
z5=strlen(z1);
za=Find("ая ия ел ок яц ий па да ца ша ба та га ка",z8);
zb=Find("аеёийоуэюяжнгхкчшщ",Left(z7,1));
zc= z2 < 0 ? -z2:z2;
zd=C(za==4,5,Find("айяь",z9));
zd=C((zc==1)||(*z9=='.')||((z4=2)&&(Find(C(*z3=='ч',"оиеу","оиеубвгджзклмнпрстфхцчшщъ"),z9)>0))||
((z4==1)&&(Find("мия мяэ лия кия жая лея",z7)>0)),9,C((zd==4) && (*z3=='ч'),2,C(z4==1,
C(Find("оеиую",z9)+Find("их ых аа еа ёа иа оа уа ыа эа юа яа",z8)>0,9,
C(*z3!='ч',C(za==1,7,C(*z9=='а',C(za>18,1,6),9)),C(((Find("ой ый",z8)>0)&&
(z5>4)&&( strcmp(Right(z1,4),"опой") != 0 )) || ((zb>10) && (za==16)),8,zd))),zd)));
ze=Find("лец вей бей дец пец мец нец рец вец аец иец ыец бер",z7);
zf=C((zd==8)&&(zc!=5),C((zb>15) || ( Find("жий ний",z7)>0),"е","о"),
C( strcmp(z1,"лев") == 0,"ьв",C((Find("аеёийоуэюя",Mid(z1,z5-3 ,1))==0)&&
((zb>11) || (zb=0)) && (ze!=45),"",C(za==7,"л",C(za==10,"к",C(za==13,"йц",
C(ze==0,"",C(ze<12,C(ze==1,"ьц","ь"),C(ze<37,"ц",C(ze<49,"йц","р"))))))))));
str1 = Mid("оыые",Find("внч",z9)+1,1);
str2 = C(Find("гжкхш",Left(z8,1))>0,"и","ы");
str3 = "а у а "+ str1 +"ме "+ str2 + " е у ойе я ю я ем" + C(za==16,"и","е")+
" и е ю ейе и и ь ьюи и и ю ейи ойойу ойойойойуюойойгомуго";
str4 = Left(z1,z5-C((zd>6) || (*zf!= '\x0'),2, C(zd>0,1,0)));
str5 = str3+C((*zf=='е') || (za==16) || ((zb>12) && (zb<16)),"и","ы")+"мм";
str6 = Mid(str5,10*zd+2*zc-3,2);
str7 = TrimRight(str6);
zf=C((zd==9) || ((z4==3) && (*z3=='ы')),z1,str4+zf+str7);
str10 = C(z4>0,ToUpper(Left(zf,1))+C((z2<0)&&(z4>1),".",Mid(zf,2)),zf);
return New( C( !z1.GetLength(),"",str10+z6));
}
//_____________________________________________________________________________
// z1 - фамилия имя отчество например Железняков Юрий Юрьевич
// z2 - Падеж ( по умолчанию = 2 - родительный)
// 2 - родительный ( нет кого? ) Железнякова Юрия Юрьевича
// 3 - дательный ( кому? ) Железнякову Юрию Юрьевичу
// 4 - винительный ( вижу кого? ) Железнякова Юрия Юрьевича
// 5 - творительный ( кем? ) Железняковым Юрием Юрьевичем
// 6 - предложный ( о ком? ) Железнякове Юрии Юрьевиче
// Если задать Z2 меньше 0, то на выходе получим от -1=Железняков Ю. Ю. до -6=Железнякове Ю. Ю.
// z3 - параметр Пол может не указываться, но при наличии фамилий с
// инициалами точное определение пола невозможно, поэтому предлагается задавать пол этим
// параметром 1 - мужской 2 - женский
// ---------------------------------------------------------------------------------------
// Бибик Галушка Цой Николайчик Наталия Петровна Герценберг Кривошей Капица-Метелица
// Если Падеж(Фио ,1 ,3), то на выходе получим Фамилия Имя Отчество и т.д.
// Если Падеж(Фио ,1 ,3,"1" ), то Фамилия
// Если Падеж(Фио ,1 ,3,"2" ), то Имя
// Если Падеж(Фио ,1 ,3,"3" ), то Отчество
// Если Падеж(Фио, 1 ,3,"12" ), то Фамилия Имя
// Если Падеж(Фио, 1 ,3,"23" ), то Имя Отчество
// Если Падеж(Фио,-1 ,3,"231" ),то И. О. Фамилия
// Если Падеж(Фио,-1 ,3,"23" ), то И. О.
// 10-11-2003 3-20
// z5 - recursion level
const char* CPadej::Padej(CString& z1, int z2, int z3, CString z4, int z5)
{
// Функция Падеж(z1,z2=2,z3=3,Знач z4="123",z5=1) Экспорт
Clear();
CString str, str1, str2, str3, str4, str5;
CString str10, str11, str15;
str10 = z4;
str11 = "ча";
str15.Format("%d", z5 );
str1 = Trim(Replace(Mid(z1,Find(z1+" "," ")+1),".",". "));
str2 = Left(z1,Find(z1+" "," ")-1);
str3 = Mid( str11+ToLow(Right(z1,1)),z3,1);
str4 = PadejWord( str2,z2, str3,z5)+" ";
str5 = Replace(str10,str15,str4);
return New( C(z5<4,Padej(str1,z2,z3, str5,z5+1),z4));
}
Cpadej oPadej;
oPadej.Padej( "Иванов Петр Алексеевич",2, 1));
oPadej.Padej( "Аликперова Нигель Амбросьевна",2, 2));
---
Best regards,
vga
Best regards,
vga
DeeJayC, тогда надо сделать маленькую мелочь в функцие :
Естественно, что моя функция не идеальная...
vga, посмотрел на твой алгоритм...тихий ужас . Я бы сдох если бы писал это все сам! Но, как говорят, искусство треьует жертв !
Код: Выделить всё
#define davatelniy 0x10
char* Padezh(char* slovo,char* okon,int pad)
{
AnsiString str = new AnsiString (slovo);
if (strcmp(okon,"")==0)
{
str.Delete(str.Pos(okon),str.Length);
switch (pad)
{
....
case 0x10:
{
str+= "у";
break;
}
default:
throw Exception("Unknown падеж :) ");
....
}
}
return str.c_str();
}
vga, посмотрел на твой алгоритм...тихий ужас . Я бы сдох если бы писал это все сам! Но, как говорят, искусство треьует жертв !
Я себе представляю такого программиста.... Большая голова, как телевизор,очки 1м на 1м...сидит за стареньким пеньком, а еще лучше за K6 или что-то вроде... Объем винта не более 2Гб,на которых меститься только вин95 и 1С. Наверняка днями не отходит от компа
Хорош флеймить!
Кстати, фамилия Панасенко по правилам русского языка не склоняется.
Кстати, фамилия Панасенко по правилам русского языка не склоняется.
Даже самый дурацкий замысел можно воплотить мастерски
AiK, Гы...точно... Это мой,кста, одноклассник. И моя училка как раз вчера говорила, что в украинском языке его фамилия склоняется, а в русском нет . Провтыкал ... надо будет подучиться