0ppa
Только самое смешное, что я случайно сначала сделал 19 задачу, а потом только 18 и у меня так получилось, что решение 19 полностью подошло для 18 задачи
Здесь делал 18-ую задачу.
0ppa
решение 19 полностью подошло для 18 задачи
Задачи в учебных курсах
специально могут быть заготовлены так, чтобы показать учащемуся реюз кода и простимулировать его взять свою программу и поменять её немного, чтобы решить другую задачу, похожую на уже решённую. Это типа учебного приёма. В реальных же задачах (из реального, дикого мира) обычно всё зависит только от тебя, от твоего мастерства писать не привязанный ни к чему код. Для этого в ООП-языках (объектно-ориентированная парадигма) существуют интерфейсы, используется приём агрегации, используется полиморфизм. В СП-языках (структурная парадигма) обычно заморачиваются на ослаблении передаваемых данных. Чем проще данные, которые модули/подпрограммы передают друг другу, тем лучше. Чем свободнее условия, в которых может выполняться подпрограмма, тем лучше. Это залог реюза такого кода. Его всегда можно повернуть чуть ли не в противоположную сторону.
Если изучишь awk (текстовый транслятор в мире Linux), там увидишь это во многих местах.
[guest@localhost ~]$ echo "a aaa" | awk '{print "field1=" $1, "field2=" $2, "match=" ($2 ~ $1 "{"length($2)"}")}'
field1=a field2=aaa match=1
[guest@localhost ~]$ echo "a aaa" | awk '{print "field1=" $1, "field2=" $2, "match=" ($2 ~ $1 "{"length($2)+1"}")}'
field1=a field2=aaa match=0
[guest@localhost ~]$
В первом случае поле “aaa” пытается проматчиться с регулярным выражением “a{3}” и у него это получается. Во втором случае поле “aaa” пытается проматчиться с регулярным выражением “a{4}” и у него это не получается.
А где мы взяли регулярное выражение само? Мы его сгенерировали на лету из текста первого поля (взяв символ поля) и текста второго поля (взяв длину этого поля в символах). В других программах, типа cut и прочих, если ты и работаешь с полями, то они являются только обрабатываемым текстом. В awk же сделали так, чтобы поля могли быть и текстами, и числами одновременно, а функции внутри awk могли принимать и текст, и число. Таким образом разработчики соединили поля с внутренними функциями awk, придав ему мощь. Как же это сделано? Это сделано через убирание лишних условий для полей и убирание лишних условий для функций. Поля не обязаны быть просто текстом, а функции не обязаны принимать лишь текст или лишь число. Любая строка может превратиться в число в любое время и любое число может превратиться в строку в любое время. В данном случае не очень заметно, как вычисленная длина, возвращённая из функции length() в виде числа, превращается в строку при выполнении операции конкатенации с единственным символом поля.
$1 "{" length($2) "}" ->
"a" "{" length($2) "}" ->
"a" "{" length("aaa") "}" ->
"a" "{" 3 "}" ->
"a{" 3 "}" ->
"a{" "3" "}" ->
"a{3" "}" ->
"a{3}"
Благодаря таким возможностям, на языке awk можно писать генераторы программ на языке awk. Программа на awk может создать программу на awk. И не только на awk. Сгенерировать пачку правильно заполненных классов на Python или C++ тоже не составит труда.
[guest@localhost ~]$ echo "a" | awk '{print length(11111)}'
5
[guest@localhost ~]$
Здесь подали число в функцию length() и она не выдала ошибку, а просто преобразовала число 11111 в строку и вернула количество символов в получившейся строке. Вот в этом фишка гибкости awk. Условие подачи в length() только строки убрано и функция стала применима к куче разных данных, среди которых могут быть и числа. Когда тебе нужно определить количество цифр в числе, тебе не нужно его делить математически или приводить к строке сначала, тем самым увеличивая код.
[guest@localhost ~]$ echo "a" | awk '{print "in 11111 there are "length(11111)" digits"}'
in 11111 there are 5 digits
[guest@localhost ~]$
[guest@localhost ~]$ awk 'BEGIN {num = 11111; print "in " num " there are " length(num) " digits"}'
in 11111 there are 5 digits
[guest@localhost ~]$
[guest@localhost ~]$ awk 'BEGIN {num = 11111; print "in " num " there are " length(num) " digits" >"file_for_" num ".txt"}'
[guest@localhost ~]$ cat file_for_11111.txt
in 11111 there are 5 digits
[guest@localhost ~]$
А тут мы сформировали на лету имя файла, куда всё это выводим. Естественно, мы можем использовать и поля, и сгенерированные строки, и любые числа для формирования имён для файлов. Попробуй в програме cut это сделать - прямо из выделенного поля в процессе обработки текста сформировать имя файла для вывода этого поля в него. Программа cut не настолько гибкая, чтобы выполнить это, как раз потому, что в ней есть куча условий типа “выделенное поле можно только вывести на экран или не выводить”, “разделитель полей можно взять только из командной строки”, “разделитель полей должен быть только одним символом” и подобных. Такие условия всё больше и больше сужают применимость самой программы и сводят на нет реюз уже написанных скриптов. Если у тебя появляются многосимвольные разделители полей, то ты уже cut не можешь задействовать. А это всего лишь небольшое изменение требований.
tags: reuse