Удалить повторяющиеся элементы в массиве по транслитерации

Тема в разделе "PHP", создана пользователем zikosa, 12 мар 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. zikosa

    zikosa Создатель

    Регистр.:
    25 ноя 2008
    Сообщения:
    22
    Симпатии:
    1
    Есть файл следующего уникального содержания:

    архитектура
    архитектураь
    архитектураъ
    суперархитектор
    суперархитекторь
    суперархитекторъ

    На выходе требуется получить файл следующего содержания:

    архитектура
    суперархитектор

    Код скрипта PHP слудующий:
    PHP:
    <?php
    error_reporting
    (7);
    set_time_limit(0);

    $storona "lat";
    $a file ("1.txt");
    $kola count ($a);
    for (
    $n=0$n<$kola$n++)
    {
    $b translitruslat (trim($a[$n]), $storona);
    $x 0;
    $y count ($r);
    for (
    $e=0$e<$y$e++)
    {
    if (
    $r[$e] == $b)
    {
    $x 1;
    break 
    1;
    }
    }
    if (
    $x == 0)
    {
    $zap fopen ("2.txt","a");
    fwrite ($zaptrim($a[$n])."\r\n");
    fclose ($zap);
    $r[] = $b;
    }
    }

    /////
    function translitruslat ($stringi$storona//$storona = "lat" -> рус-лат; $storona = "rus" -> лат-рус
    {
    $stringi preg_replace ("|([^a-zа-я\ё0-9\ ]+)|i"," ",trim($stringi));
    $stringi preg_replace ("|([\ ]+)|i"," ",trim($stringi));
    $rus = array ("ё","Ё","щ","Щ","ш","Ш","ж","Ж","я","Я","ч","Ч","ю","Ю","э","Э","ъ","Ъ","ь","ь");
    $lat = array ("jo","Jo","shh","Shh","sh","Sh","zh","Zh","jа","Jа","ch","Ch","ju","Ju","je","Je","","","","");
    if (
    $storona == "lat")
    {
    $stringi str_replace($rus,$lat,$stringi);
    $stringi strtr($stringi,"йЙцЦуУкКеЕнНгГзЗхХфФыЫвВаАпПрРоОлЛдДсСмМиИтТбБ ","jJcCuUkKeEnNgGzZhHfFyYvVaApPrRoOlLdDsSmMiItTbB-");
    }
    else
    {
    $stringi str_replace($lat,$rus,$stringi);
    $stringi strtr($stringi,"jJcCuUkKeEnNgGzZhHfFyYvVaApPrRoOlLdDsSmMiItTbB-","йЙцЦуУкКеЕнНгГзЗхХфФыЫвВаАпПрРоОлЛдДсСмМиИтТбБ ");
    }
    return(
    trim($stringi));
    }
    ?>
    Всё работет, НО !!! При файлах размерами в МБ заметна малая скорость обработки. (файл в 50Мб может обрабатываться пару суток)
    Подскажите пожалуйста идеи (код) по увеличению скорости обработки. (есть ли что то типа похожего на array_unique но через пользовательскую функцию).
     
  2. alfaexpert

    alfaexpert

    Регистр.:
    23 июл 2008
    Сообщения:
    183
    Симпатии:
    27
    Как я понимаю у тебя вручную массив обрабатывается на уникальность ?

    А не легче ли использовать функцию array_unique ?
     
  3. Flock

    Flock Постоялец

    Регистр.:
    16 июн 2007
    Сообщения:
    142
    Симпатии:
    44
    Не совсем понял все.
    Если именно такой формат почему бы каждый третий элемент не выбирать и потом делать транслитерацию?
     
  4. tenmed

    tenmed Создатель

    Регистр.:
    29 янв 2010
    Сообщения:
    10
    Симпатии:
    1
    решал похожую задачу с массивами,
    реж большой массив на маленькие, потом объеденяй и снова на uniq проверяй
    ps. я на uniq проверял через stristr(так бстрей imho)
    то есть, добавил в массив, записал в индекс $index.= "#".$value."#";

    50mb и 2 суток, че то нереально
     
  5. zikosa

    zikosa Создатель

    Регистр.:
    25 ноя 2008
    Сообщения:
    22
    Симпатии:
    1
    Смысл скрипта, что он проверяет на уникальность слова по их транслиту....
    если бы не по транслиту, то с успехом бы подошла array_unique...скорость бы была айс....десяток секунд...
    а так действительно получается пару суток, так как он сначала проходит по малому массиву транслита, а так как в 50Мб примерно 2 000 000 слов, то в итоге цифра вылезает хорошая...
    ...хм...идею про запись транслита в индекс а потом уникализацию по индексам через array_unique сейчас попробую....спасибо за идею....:)
     
  6. SeoProger

    SeoProger Писатель

    Регистр.:
    29 ноя 2008
    Сообщения:
    9
    Симпатии:
    3
    Если дело только в мягких\твердых знаках на конце, то можно перед началом обработки удалить все мягкие знаки вконце слова после гласной и твердые знаки вконце. Потом array_unique, а потом уже саму обработку.
     
  7. zikosa

    zikosa Создатель

    Регистр.:
    25 ноя 2008
    Сообщения:
    22
    Симпатии:
    1
    Спасибо всем кто помог идеями! :yahoo:
    Решил так:
    записывать в новый массив с ключами-транслитами, если такого ключа нет...
    скорость выросла примерно раз в 40 (на начальном этапе)
    конечный код получился такой:
    PHP:
    <?php
    error_reporting
    (0);
    set_time_limit(0);

    $storona "lat";
    $a file ("1/1.txt");
    $kola count ($a);
    for (
    $n=0$n<$kola$n++)
    {
    if (
    $k[translitruslat (trim($a[$n]), $storona)] == false)
    {
    $k[translitruslat (trim($a[$n]), $storona)] = trim ($a[$n]);
    }
    }
    $zap fopen ("1/2.txt","w");
    foreach (
    $k as $lo)
    {
    fwrite ($zaptrim($lo)."\r\n");
    }
    fclose ($zap);

    /////
    function translitruslat ($stringi$storona//$storona = "lat" -> рус-лат; $storona = "rus" -> лат-рус
    {
    $stringi preg_replace ("|([^a-zа-я\ё0-9\ ]+)|i"," ",trim($stringi));
    $stringi preg_replace ("|([\ ]+)|i"," ",trim($stringi));
    $rus = array ("ё","Ё","щ","Щ","ш","Ш","ж","Ж","я","Я","ч","Ч","ю","Ю","э","Э","ъ","Ъ","ь","ь");
    $lat = array ("jo","Jo","shh","Shh","sh","Sh","zh","Zh","jа","Jа","ch","Ch","ju","Ju","je","Je","","","","");
    if (
    $storona == "lat")
    {
    $stringi str_replace($rus,$lat,$stringi);
    $stringi strtr($stringi,"йЙцЦуУкКеЕнНгГзЗхХфФыЫвВаАпПрРоОлЛдДсСмМиИтТбБ ","jJcCuUkKeEnNgGzZhHfFyYvVaApPrRoOlLdDsSmMiItTbB-");
    }
    else
    {
    $stringi str_replace($lat,$rus,$stringi);
    $stringi strtr($stringi,"jJcCuUkKeEnNgGzZhHfFyYvVaApPrRoOlLdDsSmMiItTbB-","йЙцЦуУкКеЕнНгГзЗхХфФыЫвВаАпПрРоОлЛдДсСмМиИтТбБ ");
    }
    return(
    trim($stringi));
    }
    ?>
    Всем ещё раз большое спасибо!
    P.S Правда пришла идея, что неплохо было бы на начальном этапе отсортировать исходный массив к примеру по количеству символов (от наименьшего -> наибольшему)
     
Статус темы:
Закрыта.