Любой текст состоит из символов. Символ — это некоторый значок,
изображение. Один и тот же символ можно записать по-разному, например,
два человека по-разному напишут от руки букву «A»,
и даже в компьютерном представлении одна и та же буква будет выглядеть по-разному,
если ее отображать разными шрифтами, при этом это будет все равно один и тот же символ. Верно и другое:
разные символы могут быть записаны одинаково, например,
вот две разные буквы, одна — латинского
алфавита, другая - русского: «A» и «А». Несмотря на то, что они выглядят
одинаково, удобней считать их разными символами.
Итак, способ хранения текстовой информации в компьютере не связан напрямую с изображением
этого текста. Вместо символов хранятся их номера - числовые коды, а вот то, как выглядит
символ с данным числовым кодом на экране напрямую зависит от того, какой используется шрифт для отображения
символов. При этом, разумеется, следовало бы договориться о единообразном способе кодирования
символов числовыми кодами, иначе текст, записанный на одном компьютере, невозможно будет прочитать
на другом компьютере.
Первоначально договорились под кодирование одного символа отвести один байт, то есть 8 бит информации.
Таким образом можно было закодировать 256 различных значений, то есть в записи текста можно
использовать 256 различных символов. Этого достаточно, чтобы отобразить все символы латинского
алфавита, цифры, знаки препинания и некоторые другие символы. Стандарт, указывающий, какие
числовые коды соответствуют каким основным символам, называется
ASCII. В таблицу ASCII включены символы с кодами
от 0 до 127, то есть ASCII - это семибитный код. Вот так выглядит таблица ASCII:
При этом символы с кодами, меньшими 32 - это специальные управляющие символы, которые не
отображаются на экране. Например, для того, чтобы обозначить конец строки в системе
Linux используется один символ с кодом 10, а в системе Windows - два подряд идущих символа
с кодами 13 и 10, символы с кодами 48-57 соответствуют начертанию арабских цифр (обратите
внимание, символ с кодом 0 - это вовсе не символ, отображающийся на экране, как «0»),
символы с кодами 65-90 - заглавные буквы буквы латинского алфавита, а если к их кодам
прибавить 32, то получатся строчные буквы латинского алфавита. В промежутках между указанными
диапазонами находятся знаки препинания, математические операции и прочие символы.
Но в ASCII-таблицы нет русских букв! А также нет букв сотен других национальных алфавитов.
Первоначально для отображения букв национальных алфавитов использовали вторую половину возможного
значения байта, то есть символы с кодами от 128 до 255. Это приводило к множеству проблем, например,
поскольку 128 значений явно недостаточно для того, чтобы отобразить символы всех национальных алфавитов
(даже недостаточно для того, чтобы отобразить символы одного алфавита, например,
китайской письменности. Поэтому
в настоящее время для кодирования символов используется стандарт Unicode, последняя версия 10.0 которого (июнь, 2017) включает 136,755
различных символов.
Естественно, для кодирования Unicode-символов недостаточно одного байта на символ, поэтому
используются многобайтовые кодировки (для представления одного символа необходимо несколько байт).
Язык программирования Python — современный язык, поэтому он работает исключительно
с Unicode-символами.
Код символа можно определить при помощи функции ord. Эта функция
получает на вход строку, которая должна состоять ровно из одного символа.
Функция возвращает код этого символа. Например, ord('A') вернет
число 65.
Обратная функция получения по числовому коду его номера называется
chr.
Сравнение символов
Поскольку для символов заданы их числовые коды, то их можно сравнивать
при помощи операций сравения. Поскольку символы алфавита идут подряд, то результат
их сравнения будет соответствовать лексикографическому порядку, но можно сравнивать
между собой не только буквы алфавита, но и два произвольных символа.
Также в питоне определены и операции сравнения строк, которые также сравниваются
в лексикографическом порядке.
Строки и списки
Строки в языке Питон, в отличии от списков, являются неизменными объектами, то есть
в отличии от списков нельзя изменить отдельный символ строки: операция A[i] = ...
является допустимой, если A список, и недопустимой, если A — строка.
Один символ в строке можно поменять, если создать новую строку, например, следующий код меняет
i-й символ строки на символ @.
A = A[:i] + '@' + A[i+1:]
К сожалению, подобное изменение требует время, пропорциональное длине строки.
Преобразование строки S в список символов A:
A = list(S)
Преобразование списка символов в строку:
S = ' '.join(A)
или, если пробелы между символами не нужны,
S = ''.join(A)
Упражнения
Замечание по коду
При написании программ может возникнуть желание использовать «странные» константы в духе 48 или 65.
Каждая такая константа имеет смысл (откуда вы её взяли?).
Вместо самой константы пишите её смысл.
Программы, в которых встречаются подобные константы, приниматься не будут!
A: ASCII-код символа
Считайте со стандартного ввода символ и выведите его код.
Программа получает на вход один символ с кодом от 33 до 126.
A
65
B: Символ с данным ASCII-кодом
Считайте со стандартного ввода целое число и выведите ASCII-символ
с таким кодом. Решите эту задачу с использованием только одной переменной
типа int.
Программа получает на вход число от 33 до 126.
65
A
C: Таблица ASCII
Выведите все символы ASCII с кодами от 33 до 126 и их коды в следующем виде:
! 33
" 34
# 35
...
} 125
~ 126
D: Символы в заданном интервале
Выведите подряд, без пробелов, все символы, лежащие в таблице ASCII
между двумя заданными символами.
Программа получает на вход два символа, каждый в отдельной строке и должна вывести
строку, начинающуюся первым из заданных символов и заканчивающуюся вторым.
A
D
ABCD
0
9
0123456789
E: IsDigit
Для данного символа, считанного со стандартного ввода, проверьте, является ли он цифрой. Программа должна вывести слово
YES, если символ является цифрой, или слово NO.
Решение оформите в виде функции is_digit(c), возвращающей значение типа bool.
В решении нельзя использовать циклы. В решении нельзя
использовать константы с неочевидным значением типа 48 или 57.
0
YES
A
NO
F: ToUpper
Напишите функцию to_upper(c), которая переводит символ в верхний регистр, то есть для строчной
буквы латинского алфавита возвращает сооветствующую заглавную букву латинского алфавита, а для остальных символов возвращает тот же символ.
Считайте один символ со стандартного ввода и переведите его в верхний регистр. В решении нельзя использовать циклы. В решении нельзя
использовать константы с неочевидным значением.
f
F
F
F
4
4
G: Сменить регистр символа
Напишите функцию case_change(c), меняющую регистр символа,
то есть переводящую заглавные буквы в строчные, а строчные - в заглавные, остальные символы
не меняющие.
Считайте один символ со стандартного ввода, выведите результат работы данной функции.
В решении нельзя использовать циклы. В решении нельзя использовать константы с неочевидным значением.
f
F
F
f
4
4
>
H: Нижний регистр
Дана строка, возможно, содержащая пробелы. Считайте эту строку и переведите все символы этой строки в
нижний регистр. Решение оформите в виде функции to_lower(S),
получающей в качестве параметра строку и возвращающую новую строку.
Для перевода одного символа в нижний регист напишите отдельную функцию.
Hello, world!
hello, world!
I: Палиндром
Дано слово, состоящее только из заглавных и строчных латинских букв.
Проверьте, верно ли что это слово читается одинаково как справа налево, так и слева направо
(то есть является палиндромом),
если считать заглавные и строчные буквы не различающимися.
Выведите слово YES,
если слово является палиндромом и словов NO, если не является.
Решение оформите в виде функции is_palindrome(S), возвращающей
значение типа bool.
Решение должно иметь сложность \(O(n)\), где \(n\) — длина строки.
Radar
YES
YES
NO
J: Извлечь цифры
Дана строка, возможно, содержащая пробелы. Извлеките из этой строки все символы, являющиеся цифрами
и составьте из них новую строку.
Решение оформите в виде функции extract_digits(S), получающей
на вход исходную строку S и возвращающую новую строку, содержащую только цифры
данной строки.
2+2=4
224
K: Значение выражения - 1
Дана строка, состоящая из n цифр (т.е. однозначных чисел), между которыми стоит n-1
знак операции, каждый из которых может быть либо +, либо -.
Вычислите значение данного выражения.
Решение оформите в виде функции evaluate(S),
получающей в качестве аргумента строку и возвращающую ее значение.
1+2-3
0
L: Значение выражения - 2
Дано выражение одно из следующих видов: «A+B», «A-B» или «A*B»,
где A и B - целые неотрицательные числа. Определите значение этого выражения.
Решение оформите в виде функции evaluate(S).
2*2
4
100-101
-1
M: Шифр Цезаря
В шифре Цезаря
каждый символ заменяется на другой символ, третий по счету в алфавите
после данного, с цикличность. То есть символ A заменяется на D, символ B - на
E, символ C - на F, ..., символ Z на C. Аналогично строчные буквы заменяются
на строчные буквы. Все остальные символы не меняются.
Дана строка, зашифруйте ее при помощи шифра Цезаря. Решение
оформите в виде функции caesar_cipher(S, k), возвращающей
новую строку. S — исходная строка,
k — величина сдвига. Функцию нужно вызывать
со значением k=3.
Указание: сделайте функцию caesar_cipher_char(c, k),
шифрующую один символ.
In a hole in the ground there lived a hobbit.
Lq d kroh lq wkh jurxqg wkhuh olyhg d kreelw.
N: Количество слов
Дана строка, возможно, содержащая пробелы. Определите количество слов в этой строке.
Слово — это несколько подряд идущих букв латинского алфавита
(как заглавных, так и строчных).
Решение оформите в виде функции count_words(S),
возвращающее значение типа int.
При решении этой задачи нельзя пользоваться дополнительными строками и списками.
Yesterday, all my troubles seemed so far away
8
O: Самое длинное слово
Дана строка. Найдите в этой строке самое длинное слово и выведите его.
Если в строке несколько слов одинаковой максимальной длины, выведите первое из них.
Решение оформите в виде функции longest_word(S), возвращающей
значение типа str.
In a hole in the ground there lived a hobbit.
ground
P: Капитан Флинт
Капитан Флинт зарыл клад на Острове сокровищ.
Он оставил описание, как найти клад. Описание состоит из строк вида: «North 5»,
где первое слово – одно из «North», «South»,
«East», «West», а второе число – количество шагов,
необходимое пройти в этом направлении.
Напишите программу, которая по описанию пути к кладу определяет точные координаты клада, считая,
что начало координат находится в начале пути, ось OX направлена на восток, ось OY – на север.
Программа получает на вход последовательность строк указанного вида, завершающуюся строкой
со словом «Treasure!». Программа должна вывести два целых числа:
координаты клада.
North 5
East 3
South 1
Treasure!
3 4
Q: Слова с прописной буквы
Дана строка. Измените регистр символов в этой строке так, чтобы первая буква
каждого слова была заглавной, а остальные буквы - строчными.
Решение оформите в виде функции capitalize(S),
возвращающей новую строку.
In a hole in the ground there lived a hobbit.
In A Hole In The Ground There Lived A Hobbit.
R: Значение выражения - 3
Дана строка, содержащая одно или более целых неотрицательных чисел,
разделенных знаками «+» или «-». Вычислите значение
этого выражения.
Решение оформите в виде функции evaluate(S).
21+7-10
18
S: Поиск подстроки
Даны две строки, возможно, содержащие пробелы.
Выведите слово YES, если первая строка является подстрокой
второй строки или слово NO в противном случае.
Решение оформите в виде функции is_substring(Pattern, Source).
Нельзя использовать стандартные функции и методы поиска.
hole in the ground
In a hole in the ground there lived a hobbit.
YES
hole on the ground
In a hole in the ground there lived a hobbit.
NO
T: Самая частая буква
Дана строка, возможно, содержащая пробелы. Определите, какая буква
латинского алфавита (или какие буквы) в этой строке встречается
чаще всего. При решении этой задачи заглавные и строчные буквы
считаются одинаковыми, а прочие символы,
не являющиеся буквами, не учитываются.
Программа должна вывести в первой строке все буквы, которые встречаются
чаще всего в исходной строке.
Выводить буквы необходимо в заглавном написании, в алфавитном порядке, без пробелов.
Во второй строке выведите единственное число - сколько раз в данной строке встречаются эти буквы.
При решении этой задачи нельзя пользоваться вложенными циклами. Входная строка должна обрабатываться за один проход.
- We all live in the Yellow Submarine!
EL
5
U: Палиндром - 2
Дана строка, возможно, содержащая пробелы. Определите, является ли эта строка палиндромом,
при условии, что заглавные и строчные буквы не различаются, а все символы, не являющиеся
буквами, должны быть пропущены. Выведите слово YES,
если слово является палиндромом и словов NO, если не является.
Решение оформите в виде функции is_palindrome(S).
Длина входной строки может быть до 100000 символов.
При решении этой задачи нежелательно пользоваться дополнительными строками и списками, модифицировать
исходную строку.
Was it a rat I saw?
YES
abca
NO
V: IP-адрес
В сети интернет каждому компьютеру присваивается четырехбайтовый код, который принято записывать в виде
четырех чисел, каждое из которых может принимать значения от 0 до 255, разделенных точками. Вот примеры
правильных IP-адресов:
127.0.0.0
192.168.0.1
255.0.255.255
Программа получает на вход строку из произвольных символов. Если эта строка является корректной записью
IP-адреса, выведите YES, иначе выведите NO.
127.0.0.1
YES
W: Детская задача
Хорошо известна задача-шутка, в которой требуется продолжить числовой ряд:
Напишите программу, которая по данному числу k⩽25 выводит k-е число в этом ряду.
4
1211
X: Форматирование текста
Дана текстовая строка, содержащая буквы латинского алфавита, пробелы, запятые и точки.
Отформатируйте этот текст по следующим правилам:
В начале и конце строки не должно быть пробелов.
Все слова разделяются ровно одним пробелом.
Точки и запятые пишутся слитно с предыдущим словом, после знака препинания ставится пробел.
Выведите полученную строку.
Hello , world .
Hello, world.
Y: Календарь
Напечатайте календарь на месяц. Месяц может состоять из 28, 29, 30, 31 дня. Календарь на месяц состоит
из 4, 5 или 6 столбцов, заполненных числами (датами). Ширина каждого столбца - два символа, между столбцами
промежуток в один символ. Однозначные числа дополняются пробелом слева. Промежуток между столбцами - один пробел.
В каждом столбце должно быть записано хотя бы одно число.
Программа получает на вход два числа - количество дней в месяце (от 28 до 31) и день недели, на которое приходится
первое число месяца (от 1 до 7) и должна вывести календарь на указанный месяц.
Строка состоит из целых неотрицательных чисел, разделенных
знаками операций «+», «-» и «*». Вычислите значение этого
выражения выполняя действия по правилам арифметики.