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

Статус
В этой теме нельзя размещать новые ответы.

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 ($zap, trim($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 но через пользовательскую функцию).
 
Как я понимаю у тебя вручную массив обрабатывается на уникальность ?

А не легче ли использовать функцию array_unique ?
 
Не совсем понял все.
Если именно такой формат почему бы каждый третий элемент не выбирать и потом делать транслитерацию?
 
решал похожую задачу с массивами,
реж большой массив на маленькие, потом объеденяй и снова на uniq проверяй
ps. я на uniq проверял через stristr(так бстрей imho)
то есть, добавил в массив, записал в индекс $index.= "#".$value."#";

50mb и 2 суток, че то нереально
 
Смысл скрипта, что он проверяет на уникальность слова по их транслиту....
если бы не по транслиту, то с успехом бы подошла array_unique...скорость бы была айс....десяток секунд...
а так действительно получается пару суток, так как он сначала проходит по малому массиву транслита, а так как в 50Мб примерно 2 000 000 слов, то в итоге цифра вылезает хорошая...
...хм...идею про запись транслита в индекс а потом уникализацию по индексам через array_unique сейчас попробую....спасибо за идею....:)
 
Если дело только в мягких\твердых знаках на конце, то можно перед началом обработки удалить все мягкие знаки вконце слова после гласной и твердые знаки вконце. Потом array_unique, а потом уже саму обработку.
 
Спасибо всем кто помог идеями! :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 ($zap, trim($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 Правда пришла идея, что неплохо было бы на начальном этапе отсортировать исходный массив к примеру по количеству символов (от наименьшего -> наибольшему)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху