синонимайзер

И всё прочее, что касается HTML
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
lerryc
сержант
Сообщения: 191
Зарегистрирован: 2008-07-10 7:28:37
Откуда: Vladivostok

Re: синонимайзер

Непрочитанное сообщение lerryc » 2008-09-26 13:48:30

Liss, я немного не догнал твою проблему и что конкретно не работает :sorry:
Но то, что ты делаешь - нечто подобное было у меня, когда писал переводчик
чтоб был понятен кусок кода - поясню
переводилось с японского на японский (для адаптации к словарю и кодировке (японцы тоже имееют несколько японских)), а затем по выбору клиента переводилось на русский или английский
для упрощения работы и повышения скорости - словарь хранился в простом линейном файле в формате
jp1 \t rus \t eng \t jp2 \t rus_utf \t\n
собственно кусок кода

Код: Выделить всё

 $dic = file ("./jpvoc/jputf.txt");
 foreach ($dic as $tmpl) 
   {list ($jp,$rus,) = explode ("\t",$tmpl); 
    $html=str_replace($jp,$rus,$html); }
 unset ($dic);
по сути - тут не важно перевод это или замена синомимов.

выше тебе правильно указали на проблему при наличии знаков на коце слова и как быть со "строгим" соответствием?

почему я отказался от мускула - уже не упомню (толи скорость работы (слов было значительно больше 7000), толи удобства работы со словарем)

в твоем случае я бы сделал наверное так:

Код: Выделить всё

while(list($key, $val) = each($dic))
    {$html=str_replace($key,$val,$html);
     $html=str_replace($val,$key,$html);}
где dic по формату "key" => "val" достаешь из мускула,
а таблицу делаешь
uniq key "key" / uniq key "val"
что однозначно обозначит связку "слово" и "синоним"
но тут возникнет еще одна проблема - два и более синонима к одному слову
это можно решить через третий столбец - думаю сообразишь как

если что не по делу - звиняйте, несовсем догнал обозначенную проблему :sorry:
про чё понял - про то написал
машина думать не может, машина должна ехать

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 14:16:29

lerryc писал(а):выше тебе правильно указали на проблему при наличии знаков на коце слова и как быть со "строгим" соответствием?
но дали неправильное решение :smile:
lerryc писал(а):почему я отказался от мускула - уже не упомню (толи скорость работы (слов было значительно больше 7000), толи удобства работы со словарем)
зря, когда счётчик единиц превышает тысячу, пхп должен отдыхать в сторонке, тем более foreach.

lerryc
сержант
Сообщения: 191
Зарегистрирован: 2008-07-10 7:28:37
Откуда: Vladivostok

Re: синонимайзер

Непрочитанное сообщение lerryc » 2008-09-26 14:26:45

zg писал(а): зря, когда счётчик единиц превышает тысячу, пхп должен отдыхать в сторонке, тем более foreach.
абсолютно согласен (по поводу отдыхать)
думаю что и пёрл бы сработал быстрее
но я был завязан "внешними условиями"
а по поводу foreach - проверялись разные конструкции и подходы - но это не самый худший вариант из возможных - онлайн перевод в реал-тайме и на стороне клиента результат вполне приемлим был
машина думать не может, машина должна ехать

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 14:55:52

гмм... ыыыыых

тут циклов вообще не надо

Код: Выделить всё

<pre><?

// Настройка локали
setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russian.1251', 'russian');

$words = array(
    'Петя' => 'Вася',
    'Вася' => 'Егор'
);

function replace($word)
{
    global $words;
    
    if ( isset($words[$word[0]]) ) return $words[$word[0]];
    return $word[0];
}


$text = <<<TEXT
Мнолог двух пиплов.
  - Надо идти на завод, - сказал Петя.
  - На заводе холодно и мухи наглые, - возразил Вася.
TEXT;

echo 'Исходный текст:', PHP_EOL, $text, PHP_EOL;

$text = preg_replace_callback('/\w+/', 'replace', $text);

echo PHP_EOL;
echo 'Преобразованный текст:', PHP_EOL, $text, PHP_EOL;

?>

Исходный текст:
Мнолог двух пиплов.
  - Надо идти на завод, - сказал Петя.
  - На заводе холодно и мухи наглые, - возразил Вася.

Преобразованный текст:
Мнолог двух пиплов.
  - Надо идти на завод, - сказал Вася.
  - На заводе холодно и мухи наглые, - возразил Егор.
этот код может обрабатывать большие объёмы текста и большие списки синонимов при мизерных затратах... на кой тут форыч :unknown:

MAK
ст. сержант
Сообщения: 344
Зарегистрирован: 2008-09-17 2:23:21

Re: синонимайзер

Непрочитанное сообщение MAK » 2008-09-26 15:03:40

zg писал(а):
MAK писал(а):Да, вообще конечно эти грабли больше походят на баг. )) Или архитектурный проёб...
читать-то не?
http://ru.php.net/manual/ru/function.str-replace.php

ыыыыхх
Если и search , и replace - массивы, то str_replace() использует все значения массива search и соответствующие значения массива replace для поиска и замены в subject . Если в массиве replace меньше элементов, чем в search , в качестве строки замены для оставшихся значений будет использована пустая строка. Если search - массив, а replace - строка, то replace будет использована как строка замены для каждого элемента массива search .
Скажите, как вышеприведенная цитата объясняет поведение функции, когда одно значение заменяется несколько раз(как в твоем примере)? Это ведь совершенно не очевидно.
И поэтому для меня это баг. Но я не настаиваю - считай что это фича. )
Я никогда не буду менять одно слово на другое, что бы потом его-же поменять на исходное. Для кого-то другого это фича. )

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 15:10:06

MAK писал(а):Скажите, как вышеприведенная цитата объясняет поведение функции, когда одно значение заменяется несколько раз(как в твоем примере)? Это ведь совершенно не очевидно.
str_replace делает замену по всему тексту для каждого шаблона поиска, чего тут не понять? если шаблонов несколько, то вполне очевидно, что последующие шаблоны вляют на предыдущие замены.

lerryc
сержант
Сообщения: 191
Зарегистрирован: 2008-07-10 7:28:37
Откуда: Vladivostok

Re: синонимайзер

Непрочитанное сообщение lerryc » 2008-09-26 15:12:48

zg писал(а): этот код может обрабатывать большие объёмы текста и большие списки синонимов при мизерных затратах... на кой тут форыч :unknown:
красивое решение - спору нет - 5 баллов
однако насчет "мизерных затрат" - тут (не)много сомневаюсь- и пока не проверю - ничего не скажу
у меня тут уж полночь близится и проверять немедленно - не очень хочется
в понедельник, если не забуду, обязательно протестирую.
а решение - красивое, спору нет, но не очень подойдет Лиссу, имхо
=============
ps (по поводу красивости)

вместо вышеприведенного куска кода использовалось и такое:

Код: Выделить всё

$html=str_replace($jp[],$rus[],$html);
без форыча, красиво и читабельно - прироста скорости (визуально) - не ощутил
Последний раз редактировалось lerryc 2008-09-26 15:20:12, всего редактировалось 1 раз.
машина думать не может, машина должна ехать

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35429
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: синонимайзер

Непрочитанное сообщение Alex Keda » 2008-09-26 15:18:34

мне проще в сервер планку рамы докупить =)
Убей их всех! Бог потом рассортирует...

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 15:22:37

lerryc писал(а):красивое решение - спору нет - 5 баллов
затрат на цикл нет, регулярка парсится один раз, поиск синонимов осущетвляется только по хеш-массиву и только слов из текста, а не из всего массива, сам текст передаётся функции только один раз. Строковая функция поиска слова по тексту отсутсвует вообще. Тут нечему тормозить :pardon: Механизм парсит переданный ему текст извлекая из него слова, количество срабатываний функции replace равно количеству слов в тексте, а значит скорость работы не зависит от количества синонимов в массиве words. Для оптимизации можно задать минимальную длину слова, тогда количество срабатываний функции вообще снизится до минимума.
lerryc писал(а):но не очень подойдет Лиссу, имхо
))))

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 15:25:30

Лис, выложи дамп таблицы с синонимами :smile: плз, потестить

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35429
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: синонимайзер

Непрочитанное сообщение Alex Keda » 2008-09-26 15:41:58

Убей их всех! Бог потом рассортирует...

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 15:46:54

сенкс ))) ща потестим :-D

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: синонимайзер

Непрочитанное сообщение ProFTP » 2008-09-26 15:51:07

ftp://ftp.lissyara.su/users/lissyara/home_project/
что это за сопромат?
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

lerryc
сержант
Сообщения: 191
Зарегистрирован: 2008-07-10 7:28:37
Откуда: Vladivostok

Re: синонимайзер

Непрочитанное сообщение lerryc » 2008-09-26 16:02:02

zg писал(а):
сенкс ))) ща потестим :-D
и почему я такой сомнительный? :cz2:
не забудь сообщить результат и пример исходного текста
предложенный мной подход - туп, как армейский сапог
да, его производительность зависит от размера исходного шаблона и размера словаря....
но - неважно что суется на входе....
у меня подозрение, что Лисс подсовывает на вход хтмл-страницу - как твой алгоритм справится с этим?
выигрыш в твоем подходе за счет уменьшения поиска по количеству исходных слов в исходном документе
но тут появляются накладные расходы - вырезать текст, вырезать слова, найти синонимы....
а как потом эти синонимы поставить обратно в исходную хтмл-страницу с сохранением исходной вёрстки?
так что интересно увидеть реальный тест на какой-нибудь реальной 100кб хтмл-странице
имхо
машина думать не может, машина должна ехать

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 16:22:49

Код: Выделить всё

<pre><?

/**
 * Таймер
 *
 * @param string $name Имя таймера
 * @param bool $unset_timer Сбросить таймер
 * @return int
 */
function timer ( $name = 'default' , $unset_timer = true )
{
	static $timers = array();
	
	if ( !isset( $timers[ $name ] ) )
	{
		$timers[ $name ] = microtime();
		return true;
	}
	
	list($s_sec, $s_mic) = split(' ', $timers[ $name ]);
	list($e_sec, $e_mic) = split(' ', microtime());
	
	$elapsed = $e_sec - $s_sec + ( $e_mic - $s_mic );
	
	if ( $unset_timer ) unset( $timers[ $name ] );
	
	return $elapsed;
}

function replace($word)
{
    global $words;
    
    if ( isset($words[$word[0]]) ) return $words[$word[0]];
    return $word[0];
}

// Настройка локали
setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russian.1251', 'russian');

mysql_connect('localhost', 'root', '') || die('Can\'t make connect');
mysql_query('set names "cp1251"');
$res = mysql_query('select * from `test`.`news_synonyms` where `active` = 1');

// Включаем таймер
timer();

// Создание массивов
$words   = array();
$search  = array();
$replace = array();

if ( $res && mysql_affected_rows() )
{
    while ( $row = mysql_fetch_assoc($res) )
    {
        $words[ $row['source_word'] ] = $row['destination_word'];
        $search[ $row['id'] ]    = $row['source_word'];
        $replace[ $row['id'] ]   = $row['destination_word'];
    }
}

?>
Создание массивов: <?=sprintf('%.4f сек', timer('default', false))?> 
Количество синонимов в words: <?=number_format(count($words), null, null, ' ')?> 
Количество синонимов в search: <?=number_format(count($search), null, null, ' ')?> 
<?

// Для примера возьмём 
// эскиз => набросок
// хохот => смех

$testText = 'эскиз это не есть хохот, а также абориген';

?>
Исходный текст: <?=$testText?> 
<?

// Первый тест
timer('test1');
$text = preg_replace_callback('/\w+/', 'replace', $testText);
?>
Первый тест, через callback: <?=sprintf('%.4f сек', timer('test1'))?> Получилось: <?=$text?> 
<?

// Второй тест
timer('test2');
$text = str_replace($search, $replace, $testText);
?>
Второй тест, через str_replace: <?=sprintf('%.4f сек', timer('test2'))?> Получилось: <?=$text?> 
<?

// Общее время работы
?>
Общее время работы: <?=sprintf('%.4f сек', timer())?> 
результат

Код: Выделить всё

Создание массивов: 0,0220 сек 
Количество синонимов в words: 4 692 
Количество синонимов в search: 4 692 
Исходный текст: эскиз это не есть хохот, а также абориген 
Первый тест, через callback: 0,0001 сек Получилось: набросок это не кушать смех, а также туземец 
Второй тест, через str_replace: 0,0072 сек Получилось: набросок это не кушать хохот, а также абориген 
Общее время работы: 0,0294 сек 
ну... :cf: вобщем вопросы?

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 16:33:18

немного модифицировал код для проверки на больших объёмах....

Код: Выделить всё

Создание массивов: 0,0218 сек 
Количество синонимов в words: 4 692 
Количество синонимов в search: 4 692 
Исходный текст: 342 051 
Первый тест, через callback: 0,1409 сек 


Fatal error:  Allowed memory size of 8388608 bytes exhausted (tried to allocate 341945 bytes) in Z:\home\test1\www\index.php on line 88
лимит 8 метров... callback прошёл... а str_replace нет :ROFL:

поменял местами тесты

Код: Выделить всё

Создание массивов: 0,0215 сек 
Количество синонимов в words: 4 692 
Количество синонимов в search: 4 692 
Исходный текст: 342 051 


Fatal error:  Allowed memory size of 8388608 bytes exhausted (tried to allocate 341994 bytes) in Z:\home\test1\www\index.php on line 81
на str_replace вылетает.... :drinks:

UPD После того как лимит памяти был выставлен до 128(!!!!) метров (на 64 тоже вылетало), пошло...

Код: Выделить всё

Создание массивов: 0,0217 сек 
Количество синонимов в words: 4 692 
Количество синонимов в search: 4 692 
Исходный текст: 342 051 
Второй тест, через str_replace: 4,3607 сек 
Первый тест, через callback: 0,1435 сек 
Общее время работы: 4,5272 сек 
ну если на str_replace делать, то одной планкой не обойтись :roll:

MAK
ст. сержант
Сообщения: 344
Зарегистрирован: 2008-09-17 2:23:21

Re: синонимайзер

Непрочитанное сообщение MAK » 2008-09-26 18:21:03

zg писал(а):
MAK писал(а):Скажите, как вышеприведенная цитата объясняет поведение функции, когда одно значение заменяется несколько раз(как в твоем примере)? Это ведь совершенно не очевидно.
str_replace делает замену по всему тексту для каждого шаблона поиска, чего тут не понять? если шаблонов несколько, то вполне очевидно, что последующие шаблоны вляют на предыдущие замены.
Вот и я говорю, для одного это очевидно, для другого нет... )
zg, а пульни свои тесты с текстом в несколько мегабайт.

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 18:27:22

MAK писал(а):zg, а пульни свои тесты с текстом в несколько мегабайт.
нах? 300 килобайт вполне достаточно, хочешь больше, исходники я выложил :smile: на больших объёмах str_replace вылетает, смысла никакого тестить несколько мегабайт нет, если для 300 килобайт не хватает 64 мегов, то сколько понадобится для нескольких мегабайт? но если у тебя есть желание, я не против, тести ;-)

MAK
ст. сержант
Сообщения: 344
Зарегистрирован: 2008-09-17 2:23:21

Re: синонимайзер

Непрочитанное сообщение MAK » 2008-09-26 18:35:06

Я бы не простил, если бы самому не лень было... )

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-26 18:36:40

MAK писал(а):Я бы не простил, если бы самому не лень было... )
кого не простил? куда не простил? ну дак ты не поленись и тест выложи, флудить каждый может

MAK
ст. сержант
Сообщения: 344
Зарегистрирован: 2008-09-17 2:23:21

Re: синонимайзер

Непрочитанное сообщение MAK » 2008-09-27 23:26:12

zg писал(а):
MAK писал(а):Я бы не простил, если бы самому не лень было... )
кого не простил? куда не простил? ну дак ты не поленись и тест выложи, флудить каждый может
Ну ты как-будто не понял что я опечатался...
Мне лень заниматься копипастом, тем более о результатах этого теста можно догадаться. )

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-29 5:30:07

MAK писал(а):Ну ты как-будто не понял что я опечатался...
:smile: да хз... всякий народ бывает ))) бывает, что и действительно за такую фигню обижаются
MAK писал(а): тем более о результатах этого теста можно догадаться. )
))) бывает так, что из-за разной архитектуры проца, оси и сборки пхп результаты бывают с точностью до наоборот, особенно, когда дело касается строк, файлов и вычислений. Хотя, в данном случае, этого скорее всего не случится.

Но этот тест наглядно показал, что str_replace на больших массивах поиска и замены кушает непомерно много памяти, надо, думаю, попробовать с strtr сделать.

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-29 5:50:47

гм.. попробовал со strtr, оказалось, что у неё ограничение стоит на 2140 элементов в массиве поиска/замены, а рузльтат замены вполне приемлемый. Правда, если передать ей массив больше чем лимит, то никакой замены вообще не будет... и она вернёт пустую строку ((. Хотя, этот тест я проводил на пхп 5.2.3 виндовой сборки, может уже чего-то и поменялось... :unknown:

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35429
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: синонимайзер

Непрочитанное сообщение Alex Keda » 2008-09-29 8:15:14

ProFTP писал(а):ftp://ftp.lissyara.su/users/lissyara/home_project/
что это за сопромат?
это дом который я строю.
zg писал(а):гм.. попробовал со strtr, оказалось, что у неё ограничение стоит на 2140 элементов в массиве поиска/замены, а рузльтат замены вполне приемлемый. Правда, если передать ей массив больше чем лимит, то никакой замены вообще не будет... и она вернёт пустую строку ((. Хотя, этот тест я проводил на пхп 5.2.3 виндовой сборки, может уже чего-то и поменялось... :unknown:
у меня под фрёй на этой базе заменяло по вышеприведённому коду
=======
что касается рамы - у меня на моёй учётке стоит лимит в 600 чтоли мегабайт.
я как-то сортировал большие массивы. очень большие... с тех пор и стоит.
Убей их всех! Бог потом рассортирует...

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: синонимайзер

Непрочитанное сообщение zg » 2008-09-29 10:32:10

lissyara писал(а):у меня под фрёй на этой базе заменяло по вышеприведённому коду
2140 число не чётное, походу костыль, скорее всего даже только под винду, надо будет проверить :smile: