vga » 17 дек 2004, 11:21
Спасибо. Трудности как раз не в алгоритме, а найти уже готовые исходики.
Недавно нашел исходики, написанные для 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));
Спасибо. Трудности как раз не в алгоритме, а найти уже готовые исходики.
Недавно нашел исходики, написанные для 1C и на скороую руку набрасал функции, эмулирующие 1C.
Просьба не ругать, времени не было разбирать исходный код на 1C, который был просто ужасен для чтения;(
[code]
/////////////////////////////////////////////////////////////////////////////
#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));
}
[/code]
Пример использования
Cpadej oPadej;
oPadej.Padej( "Иванов Петр Алексеевич",2, 1));
oPadej.Padej( "Аликперова Нигель Амбросьевна",2, 2));