Анимация
JavaScript
|
Главная Библионтека 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 |