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

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

chomp(Owords = <STDIN>); # читать слова минус символы новой строки

foreach $word (Swords) {

$count{$word) = $count($word) + 1; # или $count($word)++

foreach $word (keys %count) (

print "$word was seen $count{$word} times\n";

Первая строка считывает строки в массив @words. Вспомните: в результате выполнения этой операции каждая строка становится отдельным элементом массива, причем символ новой строки останется нетронутым.

В следующих четырех строках осуществляется обход массива, при этом $word приравнивается по очереди каждой строке. Функция chomp отсекает символ новой строки, а потом начинается волшебство. Каждое слово используется как ключ хеша. Значение элемента, выбранного по этому ключу (слову), представляет собой значение счетчика повторений данного слова до текущего момента. Сначала в хеше элементов нет, поэтому если слово wild встречается в первой строке, то $count {"wild"} будет содержать undef. Это значение undef плюс единица оказывается равным нулю плюс единица, то есть единице. (Напомним, что при использовании в качестве числа undef означает нуль.) При следующем проходе у нас будет единица плюс единица, или два, и т.д.

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

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

Есть и другое решение, отличающееся от описанного только тем, что перед словом keys в третьей с конца строке вставлена операция sort. Без проведения операции сортировки выводимый результат кажется случайным и непредсказуемым. После сортировки все упорядочивается и становится предсказуемым. (Лично я редко использую операцию keys без сортировки; при наличии операции sort непосредственно перед keys повторные просмотры одних и тех же или похожих данных дают сопоставимые результаты.)



Глава 6 "Базовые средства ввода-вывода

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

print reverse <>;

Вас, может быть, удивит краткость этого ответа, но он, тем не менее, верен. Вот как работает этот механизм:

а) Сначала функция reverse ищет список своих аргументов. Это значит, что операция "ромб" (О) выполняется в списочном контексте. Следовательно, все строки файлов, указанных как аргументы командной строки (или данные, поступающие со стандартного ввода, если аргументов нет), считываются и преобразуются в список, каждый элемент которого состоит из одной строки.

б) Затем функция reverse меняет порядок следования элементов списка на обратный.

в) Наконец, функция print получает список-результат и выводит его

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

print "List of strings:\n"; chomp(@strings = <STDIN>); foreach (@strings) {

printf "%20s\n", $ ;

Первая строка приглашает ввести список строк.

Следующая строка считывает все строки в один массив и избавляется от символов новой строки.

В цикле foreach осуществляется проход по этому массиву с присвоением переменной $ значения каждой строки.

Функция printf получает два аргумента. Первый аргумент определяет формат "%20s\n", который означает 20-символьный столбец с выравниванием справа и символ новой строки.

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

print "Field width: "; chomp($width = <STDIN>); print "List of strings:\n"; chomp(@strings = <STDIN>); foreach (@strings) {

printf "%$(width}s\n", $ ;

В решение, данное к предыдущей задаче, мы добавили приглашение ввести ширину поля и ответ на него.



Есть еще одно изменение: строка формата printf теперь содержит ссылку на переменную. Значение переменной $width включается в эту строку до того, как printf использует данный формат. Отметим, что мы не можем записать эту строку как

printf "%$widths\n", $ ; #WRONG

потому что тогда Perl искал бы переменную с именем $widths, а не переменную с именем $width, к которой мы прибавляем букву s. По-другому это можно записать так:

printf "%Swidth"."s\n", $ ; # RIGHT

потому что символ конца строки завершает также имя переменной, защищая следующий символ от присоединения к имени.

Глава 7 Регулярные выражения

1. Вот несколько возможных ответов:

а) /а+Ь*/

б) /\\*\**/ (Вспомним, что обратная косая черта отменяет значение следующего за ней специального символа.)

в) / ($whatever) {3} / (Не Забудьте про круглые скобки, иначе множитель будет действовать только на последний символ $whatever; этот вариант не проходит также в том случае, если $whatever содержит специальные символы.)

г) /[\000-\377]{5} / или / (. I \п) { 5) / (Использовать точку без дополнительных знаков здесь нельзя, потому что она не соответствует символу новой строки.)

д) / I \s) (\s+) (\s+\2) + (\s 1 $) / (\S - это не пробельный символ, а \2 - ссылка на все, что есть "слово"; знак или альтернативный пробельный символ гарантирует, что \s+ начинается на границе пробельного символа.)

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

while (<STDIN>) (

if (/a/i SS /е/i SS /i/i SS /o/i SS /u/i) ( print;

Здесь у нас приведено выражение, состоящее из пяти операций сопоставления. Все эти операции проверяют содержимое переменной $ , куда управляющее выражение цикла while помещает каждую строку. Выражение даст значение "истина" лишь в том случае, если будут найдены все пять гласных.



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