ООО ЭкоЮнит
FAQSearchMemberlistUsergroupsFilesLog inRegisterГлавная
printer-friendly view
 
AuthorMessage
Sergey Gender:Male


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


Joined: 06 Jan 2005
Show/Hide

Post Fri 25 Sep, 2009 21:18 Download Post Reputation: 88
 Функция Русский MetaPhone, Soundex, расстояние Левенштейна и другие для 1С:Предприятия любой платформы и конфи
Функция полезна для организации поиска информации в базе данных, например фамилий, по нечёткому совпадению.

Портирована с 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, Skype 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 Visit poster's website Skype Name
Sergey Gender:Male


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


Joined: 06 Jan 2005
Show/Hide

Post Thu 13 May, 2010 22:44 Download Post Reputation: 88
 Реализация 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 **
Back to topOffline View user's profile Visit poster's website Skype Name
Sergey Gender:Male


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


Joined: 06 Jan 2005
Show/Hide

Post Sun 16 May, 2010 02:33 Download Post Reputation: 88
 Расстояние редактирования Левенштейна между строками для 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 **


Реализацию на других языках смотрите в Викиучебнике: Расстояние Левенштейна
Back to topOffline View user's profile Visit poster's website Skype Name
Display posts from previous:   

Summary Rating For >> Функция Русский MetaPhone, Soundex, расстояние Левенштейна и другие для 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 Функция. Определение размера данных для 1С: Предприятия 8.Х
Универсальная функция, позволяющая определить размер данных (хранилища значения, двоичных данных, картинки, строки). Разработана в ходе реализации проекта по взаимодействию с веб-сервером для контроля размера
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Tue 06 Oct, 2009 02:55 View latest post
Sergey
No new posts Функция. Получение содержимого адреса url (вебстраницы) методом GET для 1С: Предприятия 8.2....
взаимодействие с веб-сервером
Универсальная функция, позволяющая получить содержимое ответа HTTP-сервера. Пример использования можно посмотреть в обработке 516 из статьи Передача файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Sun 02 Mar, 2014 21:55 View latest post
Sergey
No new posts Функция. Добавление колонки данных в табличное поле формы
для конфигураций 1C: Предприятия 8.X (обычное приложение)
Функция предназначена в основном для изменения типовых конфигураций 1C: Предприятия 8.X линии УТ 10.3, УПП 1.2, БП 2.0, когда хочется что-то добавить, но не хочется сильно менять штатный код и формы. // Добавляет колонку
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Sat 03 Apr, 2010 01:38 View latest post
Sergey
No new posts Фатальная ошибка усиленного сжатия после обновления платформы
Вот такая ошибка иногда стала появляться после смены платформы на 8.3.5.1098. Какой либо логики пока не вижу, по словам пользователей вылет может происходить после ошибочного проведения документа. Кто-нибудь посоветует
Александр Романов 1Сv8: Программирование, отчёты, обработки, статьи 5 Sun 24 Aug, 2014 19:29 View latest post
Александр Романов
No new posts ТОРГ-31 (сопроводительный реестр) для конфигурации Управление торговлей 10.3
Отчет (обычное приложение)
Сопроводительный реестр сдачи документов ТОРГ-31. Тестировалось на релизе 10.3.6.8, но скорее всего будет работать и на более ранних релизах, разумеется линии 10.3. Основной макет позаимствован из обработки
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Sun 29 Aug, 2010 18:51 View latest post
Sergey






All times are UTC + 3 hours
Users browsing this topic:
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
/a
Username:

Password:

Log me on automatically each visit
  Яндекс.Метрика
CrackerTracker © 2004 - 2018 CBACK.de