Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [ 33 ] 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

Ц! текстового символа \w, за которым может следовать любое количество (включая

нуль) текстовых символов или дефисов Для того чтобы запомнить сов-

падение в специальной переменной $1, весь шаблон взят в скобки.

В следующей короткой строке кода происходят интересные вещи. Переменной $1

поочередно присваивается каждое слово, соответствующее шаблону из второй строки кода. Слова используются в качестве ключей хэша *Words. Первоначально значение пары ключ-значение не определено. Инкремент неопределенного значения, соответствующего впервые встреченному слову, помещает в элемент хэша значение 1. Если слово встречается во второй раз, ключ хэша уже существует и соответствующее ему значение увеличивается на 1, т.е. становится равным 2. Этот процесс продолжается, пока не закончатся входные данные.

После окончания работы кода в хэше будет содержаться частота появления

вводимых вами слов. Для того чтобы просмотреть полученнор распределение, можно воспользоваться следующим кодом:

foreach( keys *Words) {

print •$ SHords{Sj\n";

Нахождение уникальных элементов массива

Описанную выше методику можно использовать для нахождения тех элементов массива, которые встречаются в нем только один раз. Предположим, вы извлекли все слова из введенных данных и поместили их не в хэш, а в массив. Допустим также, что проверка наличия в массиве данного слова перед его помещением туда не выполнялась. В этом случае в полученном списке могут содержаться повторяющиеся слова.

Предположим, что во вводимой строке будет содержаться следующий список слов:

efishwQrds=(one, fish, two, fish d, fish, blue, fish);

При помощи хэша данный список слов может быть проверен на наличие уникальных элементов, как показано в листинге 7.1.

Лист1. Наксж укашх элеме масс

1: %seen=();

2: foreach(ifishwords) { 3: 5seen{? }=lr 4: }

euniquewords=keys Iseen;

-,;---H , .-"iJ.

Проведем анализ программы.

Строка I. В этой строке инициализируется временный хэ еп, предназначенный для хранения слов.

Строка 2. В этой строке совершается итерация по списку слов, переменной $ поочередно присваиваются все слова.

Строка 3. Здесь создается элемент хэша ключ которого хранится в пе-

ременной $ , а значение равно 1.

116 Часть I,



• Строка 5. Все ключи извлекаются из хэша и помешаются в массив Все повторяющиеся слова, например fish, записываются в хэш поверх друг друга, поэтому в итоге они будут представлены там только одним ключом.

Вычисление пересечения и разности массивов

Часто возникает задача найти пересечение массивов (т.е. выделить общие элементы массивов) и разность массивов (т.е. выделить элементы, которые не встречаются сразу во всех массивах). В следующем примере один список содержит имена кинозвезд, а другой - имена нолитиков. Задача - найти нолитиков, одновременно являющихся кинозвездами. Вот два этих массива:

estars=(R. Reagan, С. Eastwood, M. Jackson, Cher, S. Bono); gpols = (N.Gingrich, "S. Thurmon, R. Reagan,

S. Bono, C. Eastwood, M. Thatcher);

Код для поиска пересечения этих массивов приведен в листинге 7.2.

2. Нахожде пересечен масс

2: fcKaii (Istars) { 3: $seen{$ }=l; 4: }

5: gintersection=grep($seen{S }, вро1в);

Проведем анализ программы.

• Строка 1. Инициализируется хэ en, предназначенный для хранения имен кинозвезд.

• Строка 2. В этой строке происходит итерация по списку кинозвезд с поочередным нрисваиванием каждого имени неременной $ .

• Строка 3. Здесь создаются новые элемент%£ееп с именами кинозвезд в качестве ключей и значением 1, вместо которого можно использовать любое истинное значение.

• Строка 5. Эта строка выглядит сложнее, чем она есть на самом деле. Функции ер совершает итерацию по списку политиков Is, поочередно присваивая имя каждого политика переменной $ . Затем проверяется наличие этого имени в хэш ееп. Если имя там существует, связанное с ним значение истинно. Если значение выражения истинно, $ поступает в массив Процесс продолжается до тех пор, пока grep не проверит каждый элемент массива gpols. После окончания выполнения этого кода в массиве будут содержаться имена, встречающиеся и в Sstars,и в ipols.

Код для нахождения разности двух массивов, т.е. элементов, которые есть только в одном из массивов, практически идентичен предыдущему и приведен в листинге 7.3.



1: *seen={};

2: fcxesdi (gstars) {

3: s3EEn{$

4; } .

5 e=grep{! $£XE£i{$ J, ipol);

Изменения коснулись лишь пятой строки программы. В ней по-прежнему проверяются все имена политиков на наличие в хэши %seen, но выражение функции grep получает ложное значение, если имя найдено, и истинное - если имя не найдено. Все имена политиков, содержащиеся в Iseen, не возвращаются массиву ? difference. Для нахождения всех кинозвезд, не являющихся политиками, используется почти тот же код, лишь меняются местами массивы в stars и §pols.

Сортировка хэшей

Часто ключи хэша нужно вывести в определенном порядке, а не в том, в котором они там хранятся. Скажем, вы хотите вывести частоту появления слов в алфавитном порядке или в порядке увеличения частоты. Так как функция keys возвращает список, к нему можно применить функцию sort для упорядочивания исходного списка:

foreach ( sort key rds ) { print "$ SWords{$ }\n";

Сортировка no значениям частот ненамного сложнее. Как вы помните из 4-го занятия, "Укладка строительнгх блоков: списки и массивы", функция sort по умолчанию сортирует список согласно кодам ASCII. Если требуется более сложный вариант сортировки, функция sort вызывается вместе с блоком, определяющим порядок сортировки. Следующий код сортирует хэш по значениям:

foreach ( sort => 5Words{5b} } key rds ) { print "$, $Words{Sj\n";

Вы должны помнить, что блок функции sort вызывается многократно, причем переменные $а и в нем представляют каждую пару значений, которые должна сравнить sort. В нашем случае переменные $а и приобретают значения различных ключей хэша IWords. Вместо $a и $b сравниваются значения хэша Words, соответствующие этим ключам.

Упражнение: создание в Perl простой базы данных пользователей

ЕСЛИ вам приходилось звонить в центр гарантийного обслуживания, вы, наверное, обратили внимание, что человек на другом конце провода вначале спрашивает ваш телефонный номер, номер гарантийного талона, номер карточки социального

страхования или какой-нибудь другой номер, позволяющий компьютеру вас идентифицировать. Эти номера - не что иное, как ключи базы данных, позволяющие нолучить доступ к информации о вас. Не правда ли, все это похоже на ключи хэшей в Perl.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [ 33 ] 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122