Анимация
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

Обратите внимание: если любая из пяти гласных не обнаруживается, остальная часть выражения пропускается, потому что операция && не вычисляет свой правый аргумент, если значение левого аргумента - "ложь".

б) Еще один способ:

while (<STDIN>) {

if (/a.*e.*i.*o.*u/i) ( print;

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

в) Вот один из способов решения этой задачи:

while (<STDIN>) {

if (/"[eiou]*а["lou]*е["aou]*i["aeu]*о["aei]*u["aeio]*S/i) { print;

Выглядит уродливо, но работает. Чтобы написать такое, просто подумайте: "Что может стоять между началом строки и первой буквой а?", а затем "Что может стоять между первой буквой а и первой буквой е?". В конце концов все решится само, от вас потребуется минимум усилий.

3. Вот один из способов решения этой задачи:

while (<STDIN>) { chomp;

($user, $gcos) = (split /:/)[0,4]; (Sreal) = split (/,/, $gcos); print "$user is $real\n";

Bo внешнем цикле while производится считывание по одной строке из файла паролей в переменную $ . По достижении последней строки цикл завершается.

Вторая строка тела цикла while означает разбиение строки на отдельные переменные с использованием в качестве разделителя двоеточия. Два из этих семи значений заносятся в отдельные скалярные переменные с имеющими смысл (мы надеемся) именами.

Поле GCOS (пятое поле) затем разбивается на части с использованием в качестве разделителя символа запятой, и список-результат присваивается



одной скалярной переменной, заключенной в круглые скобки. Эти скобки играют важную роль - они указывают, что операция присваивания должна быть не скалярной, а для массива. Скалярная переменная $геа1 получает первый элемент списка-результата, а остальные элементы отбрасываются.

Оператор print затем выводит результаты на экран.

4. Вот один из способов решения этой задачи:

while (<STDIN>) ( chomp;

($gcos) = (split /:/) [4]; ($real) = split (/,/, Sgcos); ($first) = split(/\s+/, $real); $seen($first}++;

foreach (keys %seen) { if ($seen($ ) > 1) (

print "$ was seen Sseen{$ } times\n";

Цикл while работает во многом так же, как цикл while из предыдущего упражнения. Помимо разбивки строки на поля и поля GCOS на реальное имя (и другие компоненты), в этом цикле осуществляется также разбиение реального имени на собственно имя и остальную часть. После определения имени элемент хеша в %seen инкрементируется, отмечая тот факт, что мы нашли конкретное имя. Обратите внимание: оператор print в этом цикле не используется.

В цикле foreach осуществляется проход по всем ключам хеша %seen (именам из файла паролей) с присваиванием каждого из них по очереди переменной $ . Если значение, записанное в %seen по данному ключу, больше 1, значит, это имя уже встречалось. Оператор if проверяет, так ли это, и при необходимости выводит соответствующее сообщение.

5. Вот один из способов решения этой задачи:

while (<STDIN>) ( chomp;

($user, $gcos) = (split /:/)[0,4]; ($real) = split /,/, $gcos; ($first) = split(/\s+/, $real) ; $seen($first} .= " $user";

foreach (keys %names) ( $this = $names($ );

If ($this =~ /. /) {

print "$ IS used by:$this\n";



Эта программа похожа на ответ к предыдущему упражнению, но вместо того чтобы просто подсчитывать, сколько раз у нас встречалось определенное имя, мы присоединяем регистрационное имя пользователя к элементу хеша % names, указывая имя в качестве ключа. Так, для Фреда Роджерса (регистрационное имятггодегз) $names{ "Fred" ) становится равным " mrrogers", а когда появляется Фред Флинтстоун (регистрационное имя fred), $names{"Fred") становится равным " mrrogers fred". После завершения цикла у нас имеется список имен и список регистрационных имен всех имеющих данное имя пользователей.

В цикле foreach, как и в ответе к предыдущему упражнению, осуществляется проход по полученному в результате хешу, но вместо того, чтобы проверять, больше ли единицы значение элемента хеша, мы должны проверить, есть ли в этом значении более одного регистрационного имени. Для этого нужно занести значение в скалярную переменную $this и посмотреть, есть ли в нем после какого-нибудь символа пробел. Если есть, то одному реальному имени соответствуют несколько регистрационных имен, которые и указываются в выдаваемом в результате сообщении.

Глава 8 "Функции"

1. Вот один из способов решения этой задачи:

sub card I

my %card map; @card map{1..9} = qw(

one two three four five six seven eight nine

my($num) = @ ;

if ($card map{$num)) {

return $card map{$num}; ) else {

return $num;

# driver routine: while (<>) I chomp;

print "card of $ is ", Scard($ ), "\n";

Подпрограмма scard (названная так потому, что она возвращает название на английском языке для данного числа) начинается с инициализации хеша-константы, который называется %card map. Значения ему присваиваются так, что, например, $card map{ 6} равно six; это делает преобразование достаточно простым.



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