Дорого времени суток. При создании электронного учебника встала потребность организовать поиск по глоссарию (только по заголовкам). Для этого я решил использовать алгоритм нечеткого сравнения строк, взятый отсюда
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=722После перевода получилось следующее:
struct retCount{
int lngSubRows;
int lngCountLike;
};
retCount Matching(QString InputA,
QString InputB,
int lngLen)
{
retCount TempRet;
int PosStrB;
int PosStrA;
QString StrA;
QString StrB;
QString StrTempA;
QString StrTempB;
QString StrInputA = InputA.toLower();
QString StrInputB = InputB.toLower();
StrA = StrInputA;
StrB = StrInputB;
for ( PosStrA = 1; PosStrA <= (StrA.length() - lngLen + 1); ++PosStrA){
StrTempA = StrA.mid(PosStrA, lngLen);
PosStrB = 1;
for (PosStrB = 1; PosStrB <= (StrB.length() - lngLen + 1); ++PosStrB){
StrTempB = StrB.mid(PosStrB, lngLen);
if (StrTempA == StrTempB){
TempRet.lngCountLike++;
break;
}
}
TempRet.lngSubRows++;
}
return TempRet;
}
int IndistinctMatching(QString InputMatching,
QString InputStandart,
int MaxMatching = 4)
{
QString strInputMatching = InputMatching.toLower();
QString strInputStandart = InputStandart.toLower();
retCount gret;
retCount tret;
int lngCurLen; //текущая длина подстроки
//если не передан какой-либо параметр, то выход
if ((MaxMatching == 0) || (strInputMatching.length() == 0) || (strInputStandart.length() == 0)){
return 0;
}
gret.lngCountLike = 0;
gret.lngSubRows = 0;
// Цикл прохода по длине сравниваемой фразы
for (lngCurLen = 1; lngCurLen <= MaxMatching; ++lngCurLen){
//Сравниваем строку A со строкой B
tret = Matching(strInputMatching, strInputStandart, lngCurLen);
gret.lngCountLike = gret.lngCountLike + tret.lngCountLike;
gret.lngSubRows = gret.lngSubRows + tret.lngSubRows;
//Сравниваем строку B со строкой A
tret = Matching(strInputStandart, strInputMatching, lngCurLen);
gret.lngCountLike = gret.lngCountLike + tret.lngCountLike;
gret.lngSubRows = gret.lngSubRows + tret.lngSubRows;
}
if (gret.lngSubRows == 0){
return 0;
}
//избыточность сделал для удобства отладки
float rez = ((float)gret.lngCountLike/(float)gret.lngSubRows);
rez = rez*100;
return (int)rez;
}
Но эта функция жутко глючит: на одинаковых параметрах несколько раз выдавала разные результаты. Более того функция должна выдавать процент совпадения, а она выдает числа не меньше 100, а иногда и несколько тысяч.
Вставив код во Lazarus получил более вменяемые. но тоже не верные результаты.
Жду предложений.
PS облазил гугл, но функцию на C++ не нашел.