Учебные материалы по математике | Perl — сортировка по заданному критерию | Matematiku5
Вузы по математике Готовые работы по математике Как писать работы по математике Примеры решения задач по математике Решить задачу по математике online

Perl — сортировка по заданному критерию


$_="fred and barney";

$count= tr/a-z//; => $count=13, $_ не изменилось.

$count2=tr/a-z/A-Z/; => $_ будет переведено в верхний регистр, а $count2 будет равным 13.

Б. Если будет применена опция c, то символы old_strбудут рассматриваться как исключение из набора всех 256 символов, т. е. замена будет над символами дополнения.

Примеры:

$_="fred and barney";

1.  $count=tr/a-z//c; => $_ не изменилось, $count2=2

В старой строке только прописные буквы от a до z. Поэтому из добавления в переменной $_ есть только два символа пробела. Они только и подсчитываются, но не заменяются, так как newstr пуста.

2.  tr /a-z/_/c; => $_="fred_and_barney"

Все символы, не входящие в [a-z], то есть два пробела заменены на знак подчеркивания.

3.  Можно объединить опции c и d.

tr/a-z//cd; => $_="fredandbarney"

Здесь все символы, что не входят в [a-z], удалены, то есть удалены два пробела.

В. Опция s — заменяет множество экземпляров одной преобразованной буквы одним символом

$_="aaabbbcccdefghi";

tr /defgi/abcddd/s; => $_=aaabbbcccabcd

Здесь abc стали на место def, а вместо ghi получилась одна буква d. Если бы не было опции s, то получилась бы замена ghi на ddd.

В старой строке части строк не сжимаются, так как для них не задано преобразование.

Как и в команде s/// операция tr может быть применена над другой строкой. Для этого применяется операция ~=.

$a="fred and bob, lera and lora";

$b=$a;

$a=~tr/a-z/X/s;

$b=~tr/a-z/_/cs;

Получаем:

$a="X X X, X X X"

Здесь в $a каждое слово было заменено одной буквой X.

$b="fred_and_bob_lera_and_lora"

В переменной $b все группы стоящих друг за другом символов-не_букв стали одиночными знаками подчеркивания. Символы запятая и два знака пробела были заменены одним знаком подчеркивания.

Сортировка по заданному критерию

Функция sort сортирует только по возрастанию кодов ASCII.

Для сортировки в другом порядке надо определить программу сравнения, которая задает способ сравнения 2х элементов. Эта программа – как обычная подпрограмма! Она определяет – как первый аргумент соотносится со вторым аргументом.

Это может быть:

—  меньше

—  равно

—  больше

Функция sort возвращает признак соответствия двух аргументов.

Для повышения скорости выполнения у нее аргументы — $a и $b всегда и они являются глобальными переменными. Если Вы ввели в своей программе переменные $a и $b, то они небудут пересекаться с этими глобальными, то есть они всегда надежно защищены.

Признак возврата:

любое число < 0, если $a<$b

0, если $a=$b

любое число > 0, если $a>$b

"Меньше" здесь может быть:

—  действительно меньше для двух чисел;

—  "раньше" для объектов;

—  и др. Например, сравнение пятого символа или сравнение хеша по ключу или значению.

Пример для чисел

sub by_number # Необходимо обратить внимание на имя

# by_number. Если имя подпрограммы сравнения

# начинается с префикса by_, то оно составляет при

# вызове ее сложное имя вместе с функцией sort.

{ if ($a<$b)

{ return –1;

}

elsif ($a=$b)

{ return 0;

}

elsif ($a>$b)

{ return 1;

}

}

@x=(1,2,4,8,16,32,64,128,256);

@y= sort @x;

Получаем @y=(1,128,16,2,256,32,4,64,8)

@z= sort by_number @y;

Тогда @z=(1,2,4,8,16,32,64,128,256)

Для удобного чтения "сортироовка по числу" при вызове желательно использовать префикс "by" ("по").

Так как тройка (-1;0;1) в сортировке встречаются часто, то для нее в Perl применена специальная операция "челнок" со знаком <=>. Используя челнок, можно переписать программу:

sub by_number

{ $a<=>$b }

Можно сократить и вызов этой подпрограммы, написав:

@z= sort {$a<=>$b } @y;

Для сравнения строковых значений есть операция cmp.

@w=sort{$a cmp $b} @x;

Хотя это равноценно

@w= sort @x;

Операция cmp применяется для каскадного сортирования. Например, упорядочить по числу, если они не равны, а если павны, то упорядочить по строковым значениям. Поэтому программа by_number при встрече с нечисловой величиной будет ставить их в любом случайном порядке.

Для такого сравнения можно написать подпрограмму:

sub by_mostly_number

{ ($a <=> $b)||($a cmp $b);

}

Эта подпрограмма работает так: если результат "челнока" равен -1 или 1, то остальная часть пропускается. Если челнок дает 0, то выполняется операция cmp, которая выдает результат, сравнивая значения как строки.

Пример:

Есть хеш %names, у которого:

—  ключ – регистрационное имя;

—  значение – реальное имя пользователя.

Выдать отчет, в котором регистрационные и реальные имена отсортированы по порядку реальных имен.

Регистрационные имена – это keys %names;

Реальные имена – это $names{ключ}.

Поэтому для любого ключа $a мы должны проверить значение $names{$a} и провести сортировку по этому значению. Тода подпрограмма будет:

sub by_name

{ return

($names{$a} cmp $names{$b});

}

Здесь $a и $b – это ключи хеша, $names{$a} и $names{$b} – значения хеша, то есть реальные имена.

Тогда вся программа:

@sortkeys= sort by_name keys(%names);

foreach(@sortkeys)

{ print "$_ — real name of $names{$_}n";

}

Здесь производится сортировка хеша по значениям, то есть по реальныи именам, и преобразование хеша в массив ключей. У оператора foreach в качестве переменной цикла выступает встроенная переменная $_. При печати в начале выдается реальное имя, а потом регисрационное.

Что будет – если реальные имена хеша совпадут? В этом случае функция sort может выдать один раз в одном порядке, а другой – в другом. Так как при признаке, равным нулю, порядок следования не определен. Для этого надо добавить "аварийное" сравнение.

sub by_names

{ ($names{$a} cmp $names{$b})||($a cmp $b);

}

Если реальные имена совпадут, то сортировка будет производиться по регистрационным именам, которые уникальны, так как они являются ключами.

Функции, определенные пользователем

Для этого следующая конструкция:

sub имя_функции

{ операторы

}

Имя функции/подпрограммы может быть любым именем, обычно без префиксного знака, иногда – префикс &. Определение подпрограммы может быть в любом месте, обычно помещается в конец программы.

Внимание! Определение подпрограммы глобально. Если две подпрограммы имеют одинаковые имена, то второе определение заменяет первое без предупреждения.

Вызов пользовательской функции

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

Пример

sub say

{ $b = "hello, world!n"};

$a="Now ".say();

Количество вложенных вызовов ограничено только памятью.

Возвращение значений

Возвращенное значение – это результат выполнения оператора return, или последнего выражения, вычисленного в подпрограмме. Именно последнее вычисленное, а не последнее выражение, определенное в теле подпрограммы.

Пример:

sub sub_AB

{ return $a+$b;

}

$a=3; $b=4;

$c=sum_AB();

$d=3*sum_AB(); => $c=7; $d=21;

При вычислении может возвращаться список

sub list_AB

{ return($a,$b);

}

$a=5; $b=6;

@c=list_AB(); => @c=(5,6)

Все это были тривиальные примеры. Теперь рассмотрим, как в подпрограмму мы можем передавать значенич.

Аргументы

В Perl после вызова подпрограммы следует список в круглых скобках, что обеспечивает автоматическое присваивание элементов данного списка на период выполнения этой подпрограммы специальной переменной с именем @_.

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

$_[0] – первый элемент массива @_

$_[1] – второй элемент массива @_

и т. д.

@_[1..$#] до последнего.

Необходимо заметить, что $_[0] и переменная $_ — это разные переменные.

Пример:

sub say

{ print "$_[0],$_[1]!n";}

……………………………………………………

say ("hello","world");

say ("goodbye","cruel world"); # cruel world – жестокий мир

Избыточные параметры — игнорируются.

Недостающие параметры дают undef.

Внимание! Переменная @_ — локальна для подпрограммы, то есть создается всегда локальная копия этой переменной.

Все переменные в подпрограмме обычно глобальные.

Как получить локальные переменные в функциях?

Для этого оператор my, который получает список имен переменных и создает их локальные копии.

my ($sum); my($sum)=0; # Скалярная переменная. Ее можно

# сразу проинициализировать.

my (@result); # Массив

my ($n,@values); # Две скалярные и массив

Внимание! Скобки при my можно не записывать, если это не список.

Например:

Наташа

Автор

Наташа — контент-маркетолог и блогер, но все это не мешает ей оставаться адекватным человеком. Верит во все цвета радуги и не верит в теорию всемирного заговора. Увлекается «нефрохиромантией» и тайно мечтает воссоздать дома Александрийскую библиотеку.

Распродажа дипломных

 Скидка 30% по промокоду Diplom2020