Username:
Password:
 Log me on automatically each visit
 
Aeroion.Ru
Форумы сервера Aeroion.Ru
Welcome

Aeroion.Ru Forum Index
  » Технические форумы
   » 1Сv8: Программирование, отчёты, обработки, статьи
    » Функция Русский MetaPhone и другие для 1С:Предприятия любой платформы и конфигурации
   нечёткий поиск поиск информации
printer-friendly view
AuthorФункция Русский MetaPhone и другие для 1С:Предприятия любой платформы и конфигурации
Sergey Gender:Male


Местный босс - администратор


Joined: 06 Jan 2005
Location: Оренбург
Posts: 1127
Last Visited: Today at 01:43
Кредиты: 3594
Reputation: 47
Age: 41
Zodiac: Aquarius Pig

Функция полезна для организации поиска информации в базе данных, например фамилий, по нечёткому совпадению.

Функция была портирована с Visual Basic несколько лет назад, в ходе решения задачи по поиску контрагентов или физлиц (уже не помню) по нечёткому совпадению.
Обнаружил случайно, копаясь в старых работах на платформе 7.7, и решил выложить в надежде, что может быть, кому-то пригодится. Хочу заметить, что для платформы 8.1 и 8.2 может быть неактуально, в связи со штатными возможностями нечёткого поиска.

Оригинал функции и статья по теме находится по адресу «Как ваша фамилия», или Русский MetaPhone .

Code:
//________________________________________________________________________
//
// ** MetaPhone() algorithm **
// ** coded by Sergey (aka Porutchik) * 2006 http://forum.aeroion.ru
//
// based on description :
// © Peter Kankowski, 2002
// http://www.kankowski.narod.ru/dev/metaphoneru.htm
//
Функция  MetaPhoneRu(Знач W) Экспорт
   
//Заменяет ЙО, ЙЕ и др.; неплохо оптимизирован.

    //alf - алфавит кроме исключаемых букв, cns1 и cns2 - звонкие и глухие
    //согласные, cns3 - согласные, перед которыми звонкие оглушаются,
    //  ch, ct - образец и замена гласных
   
alf = "ОЕАИУЭЮЯПСТРКЛМНБВГДЖЗЙФХЦЧШЩЁЫ";
   
cns1 = "БЗДВГ";
   
cns2 = "ПСТФК";
   
cns3 = "ПСТКБВГДЖЗФХЦЧШЩ";
   
ch = "ОЮЕЭЯЁЫ";
   
ct = "АУИИАИА";
   
//S, V - промежуточные строки, i - счётчик цикла, B - позиция
    //найденного элемента, c$ - текущий символ, c_old$ - предыдущий символ
   
S= "";
   
V= "";
   
i= 0;
   
B= 0;
   
c= "";
   
old_c = "";

   
//Переводим в верхний регистр, оставляем только
    //символы из alf и копируем в S:
   
W = Врег(W);
    Для
i = 1 По СтрДлина(W) Цикл
       
c = Сред(W, i, 1);
        Если
Найти(alf, c) > 0 Тогда
           
S = S + c;
        КонецЕсли;
    КонецЦикла;
    Если
СтрДлина(S) = 0 Тогда
        Возврат
"";
    КонецЕсли;

   
//Сжимаем окончания:
   
Врем = Прав(S, 6);
    Если
Врем = "ОВСКИЙ"  Тогда
       
S = Лев(S, СтрДлина(S) - 6) + "@";
    ИначеЕсли
Врем = "ЕВСКИЙ" Тогда
       
S = Лев(S, СтрДлина(S) - 6) + "#";
    ИначеЕсли
Врем = "ОВСКАЯ" Тогда
       
S = Лев(S, СтрДлина(S) - 6) + "$";
    ИначеЕсли
Врем = "ЕВСКАЯ" Тогда
       
S = Лев(S, СтрДлина(S) - 6) + "%";
    Иначе
       
Врем = Прав(S, 4);
        Если (
Врем = "ИЕВА") ИЛИ (Врем = "ЕЕВА") Тогда
           
S = Лев(S, СтрДлина(S) - 4) + "9";
        ИначеЕсли (
Врем = "ОВНА") ИЛИ (Врем = "ЕВНА") Тогда
           
S = Лев(S, СтрДлина(S) - 4) + "8";
        ИначеЕсли (
Врем = "ОВИЧ") ИЛИ (Врем = "ЕВИЧ") Тогда
           
S = Лев(S, СтрДлина(S) - 4) + "7";
        Иначе
           
Врем = Прав(S, 3);
            Если (
Врем = "ОВА") ИЛИ (Врем = "ЕВА") Тогда
               
S = Лев(S, СтрДлина(S) - 3) + "9";
            ИначеЕсли
Врем = "ИНА" Тогда
               
S = Лев(S, СтрДлина(S) - 3) + "1";
            ИначеЕсли (
Врем = "ИЕВ") ИЛИ (Врем = "ЕЕВ") Тогда
               
S = Лев(S, СтрДлина(S) - 3) + "4";
            ИначеЕсли
Врем = "НКО" Тогда
               
S = Лев(S, СтрДлина(S) - 3) + "3";
            Иначе
               
Врем = Прав(S, 2);
                Если (
Врем = "ОВ") ИЛИ (Врем = "ЕВ") Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "4";
                ИначеЕсли
Врем = "АЯ" Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "6";
                ИначеЕсли (
Врем = "ИЙ") ИЛИ (Врем = "ЫЙ") Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "7";
                ИначеЕсли (
Врем = "ЫХ") ИЛИ (Врем = "ИХ") Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "5";
                ИначеЕсли (
Врем = "ИН") Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "8";
                ИначеЕсли (
Врем = "ИК") ИЛИ (Врем = "ЕК") Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "2";
                ИначеЕсли (
Врем = "УК") ИЛИ (Врем = "ЮК") Тогда
                   
S = Лев(S, СтрДлина(S) - 2) + "0";
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;

   
//Оглушаем последний символ, если он - звонкий согласный:
   
B = Найти(cns1, Прав(S, 1));
    Если
B > 0 Тогда
       
S = Сред(S, СтрДлина(S)-1, 1);
       
S = S + Сред(cns2, B, 1);
    КонецЕсли;
   
old_c = " ";
   
//Основной цикл:
   
Для i = 1 По СтрДлина(S) Цикл
       
c = Сред(S, i, 1);
       
B = Найти(ch, c);
        Если
B > 0 Тогда //Если гласная
           
Если (old_c = "Й") ИЛИ (old_c = "И") Тогда
                Если (
c = "О") ИЛИ (c = "Е") Тогда //Буквосочетания с гласной
                   
old_c = "И";
                   
V = Сред(V, СтрДлина(V)-1, 1);
                   
V = V + old_c;
                Иначе
//Если не буквосочетания с гласной, а просто гласная
                   
Если c <> old_c Тогда
                       
V = V + Сред(ct, B, 1);
                    КонецЕсли;
                КонецЕсли;
            Иначе
//Если не буквосочетания с гласной, а просто гласная
               
Если c <> old_c Тогда
                       
V = V + Сред(ct, B, 1);
                КонецЕсли;
            КонецЕсли;
        Иначе
//Если согласная
           
Если c <> old_c Тогда //для «Аввакумов»
               
Если Найти(cns3, c) > 0 Тогда //Оглушение согласных
                   
B = Найти(cns1, old_c);
                КонецЕсли;
                Если
B > 0 Тогда
                   
old_c = Сред(cns2, B, 1);
                   
V = Сред(V, СтрДлина(V)-1, 1);
                   
V = V + old_c;
                КонецЕсли;
                Если
c <> old_c Тогда
                   
V = V + c; //для «Шмидт»
               
КонецЕсли;
            КонецЕсли;
        КонецЕсли;
       
old_c = c;
    КонецЦикла;
    Возврат
V;
КонецФункции
// ** MetaPhoneRu() algorithm **

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, слать емайлы, пытаться писать в приват. Спасибо за понимание.
Please do not PM, ICQ or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
Back to topOffline View user's profile Skype Name
Sergey Gender:Male


Местный босс - администратор


Joined: 06 Jan 2005
Location: Оренбург
Posts: 1127
Last Visited: Today at 01:43
Кредиты: 3594
Reputation: 47
Age: 41
Zodiac: Aquarius Pig

Post Thu 13 May, 2010 22:44 Download Post
 Реализация Soundex алгоритма на 1С: Предприятии.
Ещё одна находка на винте.
Реализация Soundex алгоритма на 1С: Предприятии. Как видно из комментариев, написана не мною, я всего лишь заменил англоязычные синонимы зарезервированных слов на русские. Или же она тоже портировалась с чего-то? В общем результаты работы тогда меня не устроили, Шереметьево и ещё какие-то не совсем цензурные слова считались одинаковыми.

Code:

// ** Soundex() algorithm **
// ** coded by Andy D Sokolow (aka Denil) * 2001
//
// based on description :
//
// [#1] http://www.nara.gov/genealogy/coding.html
// [#2] http://www.searchforancestors.com/soundex.html ('W'&'H') <<< !!!
//
// {rus_tab<=>lat_tab} таблица транслитерации взята отсюда
// http://softlab.od.ua/products/ftsib/index.html
//
Функция Soundex(Знач _str) Экспорт

    Перем
char2hash[7];
   
//...
   
s = СокрЛП(Врег(_str));
   
l = СтрДлина(s);
    Если
l=0 Тогда
        Возврат(
"0000");
    КонецЕсли;
   
//...
   
char2hash[1] = "HWAEIOUY"; // x
   
char2hash[2] = "BFPV"; // 1
   
char2hash[3] = "CGJKQSXZ"; // 2
   
char2hash[4] = "DT"; // 3
   
char2hash[5] = "L"; // 4
   
char2hash[6] = "MN"; // 5
   
char2hash[7] = "R"; // 6
    //...
   
rus_tab = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯЬЪ";
   
lat_tab = "ABVGDEEGZIIKLMNOPRSTUFHCHHHIAWAXY";
   
//...
   
rs = "";
   
lh = -1;

    Для
i=1 По l Цикл
   
//...
       
c = Сред(s,i,1);
       
p = Найти(rus_tab,c);
       
//...
       
Если p>0 Тогда
           
c=Сред(lat_tab,p,1);
        КонецЕсли;
// translit :: r2l...

       
Если Найти(lat_tab,c)=0 Тогда
            Продолжить;
        КонецЕсли;
       
//...
       
Для h=1 По 7 Цикл
           
//...
           
Если Найти(char2hash[h],c)>0 Тогда
                Если
lh<>h Тогда
                    Если
lh=-1 Тогда
                       
rs=c;lh=h;
                    Иначе
                        Если
h=1 Тогда
                           
//
                            // если используется href[#1], тогда надо следующую строчку
                            // раскомментировать :: там у НИХ какая-то неразбериха;o)
                            //
                           
Если (c="W") ИЛИ (c="H") Тогда
                                Прервать;
                            КонецЕсли;
                           
lh=h;
                            Прервать;
                        КонецЕсли;
                       
lh = h;
                       
rs = rs+(h-1);
                    КонецЕсли;
                КонецЕсли;
                Прервать;
            КонецЕсли;
       
//...
       
КонецЦикла;
       
//...
       
Если СтрДлина(rs)>=4 Тогда
            Прервать;
        КонецЕсли;
   
//...
   
КонецЦикла;
   
//...
   
rs = rs+Формат(0,"N(0)"+(4-СтрДлина(rs)));
   
//...
   
Возврат(rs);

КонецФункции
//Soundex() algorithm **

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, слать емайлы, пытаться писать в приват. Спасибо за понимание.
Please do not PM, ICQ or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
Back to topOffline View user's profile Skype Name
Sergey Gender:Male


Местный босс - администратор


Joined: 06 Jan 2005
Location: Оренбург
Posts: 1127
Last Visited: Today at 01:43
Кредиты: 3594
Reputation: 47
Age: 41
Zodiac: Aquarius Pig

Post Sun 16 May, 2010 02:33 Download Post
 Расстояние редактирования Левенштейна между строками для 1С: Предприятия 8.Х.
Предложенный на www.infostart.ru вариант вычисления [url=http://ru.wikipedia.org/wiki/Расстояние_Левенштейна]расстояния Левенштейна между строками[/url] для 1С: Предприятия 8.Х.
Здесь эта функция приведена с небольшими поправками в коде, а также английские термины заменены на русские.

Code:
// ** LevenshteinDistance() algorithm **
// ** coded by Михаил (aka mikeA) * 2010
//
// Функция для вычисления расстояния Левенштейна между строками.
// Портировано с Visual Basic в 1С8.
//
// based on description :
// Оригинальный текст: http://www.merriampark.com/ld.htm#VB
//
Функция LevenshteinDistance(Знач s, Знач t) Экспорт

   
// Step 1
   
n = СтрДлина(s);
   
m = СтрДлина(t);

    Если (
n = 0) ИЛИ (m = 0) Тогда
        Возврат
Макс(m, n);
    КонецЕсли;

   
d= Новый Массив(n + 1, m + 1);

   
// Step 2
   
Для i = 0 По n Цикл
       
d[i][0] = i;
    КонецЦикла;

    Для
j = 0 По m Цикл
       
d[0][j] = j;
    КонецЦикла;

   
// Step 3
   
Для i = 1 По n Цикл

       
s_i = Сред(s, i, 1);

       
// Step 4
       
Для j = 1 По m Цикл

           
t_j = Сред(t, j, 1);

           
// Step 5
           
Если s_i = t_j Тогда
               
cost = 0;
            Else
               
cost = 1;
            КонецЕсли;

           
// Step 6
           
d[i][j] = Мин(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);

        КонецЦикла;

    КонецЦикла;

   
// Step 7
   
Возврат d[n][m];

КонецФункции
//LevenshteinDistance() algorithm **


Реализацию на других языках смотрите в Викиучебнике: Расстояние Левенштейна

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, слать емайлы, пытаться писать в приват. Спасибо за понимание.
Please do not PM, ICQ or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
Back to topOffline View user's profile Skype Name
Display posts from previous:   

Summary Rating For >> Функция Русский MetaPhone и другие для 1С:Предприятия любой платформы и конфигурации
Average Rating: 5.00 :: Min Rating: 5 :: Max Rating: 5 :: Number of Ratings: 1
Choose Rating: 1   2   3   4   5  


Similar Topics
Topic Author Forum Replies Last Post
No new posts «Как ваша фамилия», или Русский MetaP...
нечёткий поиск информации
Sergey Разное 1 Thu 13 May, 2010 15:47 View latest post
Sergey
No new posts [RC] Advanced Similar (Related) Topic...
автоматический поиск похожих по смысл...
Sergey Поддержка и моды для phpBB3 89 Sat 21 Jan, 2012 16:35 View latest post
Sergey
No new posts Мод Search Similar Topics Before Post...
автоматический поиск похожих по смысл...
Sergey Поддержка и моды для phpBB2 17 Tue 12 Oct, 2010 19:43 View latest post
Sergey
No new posts Функция. Определение размера данных д... Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Tue 06 Oct, 2009 02:55 View latest post
Sergey
No new posts ТОРГ-31 (сопроводительный реестр) для...
Отчет
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Sun 29 Aug, 2010 18:51 View latest post
Sergey




All times are UTC + 3 Hours
All times are synchronized with the forum server time
Users browsing this topic:3 Guests
Registered Users: None

Jump to:   
printer-friendly view
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum