Задача: перед нами некоторый довольно длинный текст в переменной $text. Необходимо выделить из него все слова и оставить из них только уникальные. Результат должен быть представлен в виде списка, отсортированного в алфавитном порядке. Решение этой задачи может потребоваться, например, при написании индексирующей поисковой системы на PHP.
Решение: воспользуемся функцией split() и ассоциативным массивом.
Листинг 22.1. Отбор уникальных слов
// Эта функция выделяет из текста в $text все уникальные слова и
// возвращает их список, отсортированный в алфавитном порядке.
function GetUniques($text)
{ // Сначала получаем все слова в тексте
$Words=split("[[:punct:][:blank:]]+",$text);
$Uniq=array(); // список уникальных слов
$Test=array(); // хэш уже обработанных слов
// Проходимся по всем словам в $Words и заносим в $Uniq уникальные
foreach($Words as $v) {
$v=strtolower($v); // в нижний регистр
// Слово уже нам встречалось? Если нет, то занести в $Uniq
if(!@$Test[$v]) $Uniq[]=$v;
// Указать, что это слово уже обрабатывалось
$Test[$v]=1;
}
// Наконец, сортируем список
sort($Uniq);
return $Uniq;
}
Данный пример довольно интересен, т. к. он имеет довольно большую функциональность при небольшом объеме. Его "сердце" — функция split() и цикл перебора слов с отбором уникальных. Мы используем алгоритм, основанный на применении ассоциативного массива для отбора уникальных элементов. Как он работает — надеюсь, ясно из комментариев.
Теперь мы можем воспользоваться функцией из листинга 22.1, например, в таком контексте:
$fname="sometext.txt";
$f=fopen($fname,"r");
$text=fread($f,filesize($fname));
fclose($f);
$Uniq=GetUniques($text);
foreach($Uniq as $v) echo "$v ";
Интересно будет отметить, что функция preg_split(), которая работает с регулярными выражениями в формате PCRE, и которую мы не рассматриваем в этой книге, показывает гораздо лучшую производительность в этом примере, чем split() — чуть ли не в 3 раза быстрее! Если вам нужна максимальная производительность, пожалуй, будет лучше воспользоваться именно ей, но прежде почитайте что-нибудь о Perl и его регулярных выражениях — например, в замечательной книге Perl Cookbook Òîìà Êðèñòèàíñåнà è Íàòà Òîðêèíãòîíà (русское издание: "Библиотека программиста. Perl", издательство Питер, 2000).[E89]