9-4 Python
9-4 Python
2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
1 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Сравнение строк
Строки можно сравнивать между собой так же, как числа.
Например, можно проверить равенство двух строк:
password = input( "Введите пароль:" )
if password == "sEzAm":
print( "Слушаюсь и повинуюсь!" )
else:
print( "No pasaran!" )
Можно также определить, какая из двух строк больше, ка-
кая – меньше. Если строки состоят только из русских или толь-
ко из латинских букв, то меньше будет та строка, которая идет
раньше в алфавитном списке. Например, слово «паровоз» будет
«меньше», чем слово «пароход»: они отличаются в пятой букве и
«в» < «х». Это можно проверить экспериментально, например, с
помощью такой программы:
2 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
s1 = "паровоз"
s2 = "пароход"
if s1 < s2:
print( s1, "<", s2 )
elif s1 == s2:
print( s1, "=", s2 )
else:
print( s1, ">", s2 )
Но откуда компьютер знает, что такое алфавитный поря-
док? Оказывается, при сравнении используются коды символов
(вспомните материал 8 класса). В современных кодировках1 и
русские, и английские буквы расположены в алфавитном по-
рядке, то есть код буквы «в» меньше, чем код буквы «х».
С помощью программы сравните пары слов и сделайте вы-
воды:
пар – парк Пар – пар
steam – Пар Steam – steam
5Steam – Steam
Не используя программу, сравните пары слов:
парта – парк ПАрта - Парк
СПАМ – Spam ПОЧТА – spam
ПО4та – ПОЧта почТА - Post
55 – 66 9 - 128
Сложение и умножение
Оператор «+» используется для «сложения» (объединения,
сцепления) строк. Эта операция иногда называется конкатена-
ция. Например:
s1 = "Привет"
s2 = "Вася"
s = s1 + ", " + s2 + "!"
Обращение к символам
В Python каждый символ строки имеет свой номер (индекс),
причём нумерация, как и во многих других языках программи-
рования (С, C++, Java), всегда начинается с нуля.
Индекс можно понимать как смещение символа от начала
строки. Первый по счёту символ имеет нулевое смещение (нахо-
дится в самом начале строки), поэтому его индекс – 0:
индексы 0 1 2 3 4 5 6
hello = " П р и в е т ! "
К любому символу можно обратиться по индексу, записав
индекс в квадратных скобках после имени строки:
print( hello[1] ) # р
print( hello[5] + hello[2] + "к" ) # тик
В языке Python можно указывать отрицательные индексы.
Это значит, что отсчёт ведётся от конца строки, так что символ
hello[-1] – это последний символ строки hello:
индексы –7 –6 –5 –4 –3 –2 –1
hello = " П р и в е т ! "
Чтобы рассчитать «обычную» позицию символа в строке, к
отрицательному индексу нужно добавить длину строки. Напри-
мер,
hello[-1] = hello[len(hello)-1] = hello[6]
Предыдущую программу можно было переписать, используя
отрицательные индексы:
4 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
print( hello[-6] ) # р
print( hello[-2] + hello[-5] + "к" ) # тик
Если указать неправильный индекс, произойдёт ошибка – вы-
ход за границы строки, и программа завершится аварийно. Для
строки из семи символов правильные индексы – от «–7» до 6.
5 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Срезы
Для того, чтобы выделить часть строки (подстроку), в языке
Python применяется операция получения среза (англ. slicing).
Например, s[3:8] означает «символы строки s с 3-го по 7-й» (то
7 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Встроенные методы
В Python существует множество встроенных алгоритмов для
работы с символьными строками. Многие из них вызываются с
помощью точечной записи, они называются методами обработ-
ки строк. Например, методы upper и lower позволяют перевес-
ти строку соответственно в верхний и нижний регистр:
s = "aAbBcC"
sUp = [Link]() # sUp = "AABBCC"
sLow = [Link]() # sLow = "aabbcc"
Слева от точки записывается имя строки (или сама строка в ка-
вычках), к которой нужно применить метод, а справа от точки –
название метода. Например, возможна такая запись:
sWow = "Wow!".upper() # "WOW!"
Здесь метод upper применяется к строке «Wow!».
Методы строк мы уже использовали, когда выводили дан-
ные на экран с помощью метода format:
a = 5
b = 4
print( "{}+{}={}".format(a,b,a+b) )
Ещё один метод, isdigit, проверяет, все ли символы стро-
ки – цифры, и возвращает логическое значение:
s = "ab1c"
print( [Link]() ) # False
s = "123"
print( [Link]() ) # True
Полезный метод strip (по-английски – лишать) удаляет
пробелы в начале и в конце строки:
sRaw = " Python & C++ "
sClear = [Link]() # sClear = "Python & C++"
8 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Удаление и вставка
Для удаления части строки нужно составить новую строку,
объединив части исходной строки до и после удаляемого участ-
ка:
s = "0123456789"
s = s[:3] + s[9:]
Запишите в тетради, какое значение будет иметь пе-
ременная s после выполнения этого фрагмента програм-
мы. Проверьте ответ с помощью компьютера.
Срез s[:3] означает «от начала строки до символа s[3], не
включая его», а запись s[9:] – «все символы, начиная с s[9]
до конца строки». Таким образом, в переменной s остаётся зна-
чение «0129».
С помощью срезов и сцепления строк можно также вставить
новый фрагмент внутрь строки:
s = "0123456789"
s = s[:3] + "ABC" + s[3:]
Запишите в тетради, какое значение будет иметь
переменная s после выполнения этого фрагмента програм-
мы.
9 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
print( "Номер символа", n )
else:
print( "Символ не найден." )
Метод find возвращает целое число – индекс символа, с
которого начинается образец (буква «с») в строке s. Если образец
в строке встречается несколько раз, функция находит первый из
них. В рассмотренном примере в переменную n будет записано
число 3.
Выясните экспериментально, какое значение возвращает
метод find, если образец для поиска не найден в строке.
Аналогичный метод rfind (от англ. reverse find – искать в
обратную сторону) ищет последнее вхождение образца в строку.
Для той же строки s, что и в предыдущем примере, метод rfind
вернёт 12 (индекс последней буквы «с»):
s = "Здесь был Вася."
n = [Link]( "с" ) # n = 12
Как можно найти вторую букву «с» с начала строки?
Вводится строка, в которой сначала записана фамилия
человека, а затем через пробел – его имя, например,
"Семёнов Андрей". Запишите операторы, которые позво-
ляют:
найти номер пробела, разделяющего фамилию и имя,
и записать его в переменную p;
выделить из строки фамилию и записать её в
переменную fam;
выделить из строки имя и записать его в переменную
name;
приписать перед фамилией первую букву имени,
точку и пробел.
10 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
11 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Выводы:
Символьная строка – это последовательность символов.
Длина строки – это количество символов в строке.
Подстрока – это часть символьной строки.
При обращении к отдельному символу строки его номер запи-
сывают в квадратных скобках. Нумерация символов в строке в
языке Python начинается с нуля.
Знак «+» при работе со строками означает объединение (кон-
катенацию) строк.
12 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Вопросы и задания
1. Во многих языках (в том числе и в Python) можно использо-
вать массивы символов, то есть массивы, каждый элемент
которых – один символ. Чем отличается строка от массива
символов?
2. Чем отличается действие оператора «+» для чисел и для
символьных строк?
3. Как определить, что при поиске в строке образец не найден?
4. Как бы вы искали первый символ «с» с конца строки, если
бы не было метода rfind?
Задачи
1. Напишите программу, которая заменяет в символьной стро-
ке все точки на нули и все буквы X на единицы. Например,
из строки '..XX..X.' должна получиться строка '00110010’.
2. Напишите программу, которая выполняет инверсию битов в
символьной строке: заменяет в ней все нули на единицы и
наоборот. Например, из строки «00110010» должна полу-
читься строка «11001101».
3. Введите битовую строку и дополните её последним битом,
который должен быть равен 0, если в исходной строке чёт-
ное число единиц, и равен 1, если нечётное (в получившей-
ся строке должно всегда быть чётное число единиц). На-
пример, из строки «00110010» должна получиться строка
«001100101».
13 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
14 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
15 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Рис. 4.1.
С каким элементом нужно поменять местами элемент
A[i]? Зависит ли ваш ответ от свойств числа i?
Сергей написал такой алгоритм для решения задачи 1:
for i in range(N):
# поменять местами A[i] и A[i+1]
Выполните его вручную этот алгоритм для массива [1, 2,
3, 4] (N = 4). Объясните результат. Найдите ошибки в
алгоритме Сергея.
Обратите внимание, что при выполнении алгоритма Сер-
гея на последнем шаге цикла мы будем менять местами эле-
16 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Реверс массива
Задача 2. Требуется выполнить реверс массива, то есть пе-
реставить элементы массива в обратном порядке, так чтобы
первый элемент стал последним, а последний – первым:
0 1 2 N–3 N–2 N–1
7 12 5 34 40 23
0 1 2 N–3 N–2 N–1
23 40 34 5 12 7
Рис. 4.2.
С каким элементом нужно поменять местами элемент
A[0]? элемент A[1]? элемент A[i]?
Если индекс первого элемента в паре увеличивается на 1, а
индекс второго элемента уменьшится на 1, что можно
сказать о сумме индексов этих элементов?
17 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Сортировка массивов
Сортировка – это расстановка элементов списка (массива) в
заданном порядке.
Возникает естественный вопрос: «зачем сортировать дан-
ные?». На него легко ответить, вспомнив, например, работу со
словарями: сортировка слов по алфавиту облегчает поиск нуж-
ной информации.
Для чисел обычно используют сортировку по возрастанию
(каждый следующий элемент больше предыдущего) или убыва-
нию (следующий элемент меньше предыдущего). Если в масси-
ве есть одинаковые элементы, их можно расставить по неубы-
ванию (каждый следующий элемент не меньше предыдущего)
или невозрастанию.
Математики и программисты изобрели множество способов
сортировки. В целом их можно разделить на две группы: 1) про-
стые, но медленно работающие (на больших массивах) и 2)
сложные, но быстрые.
Мы изучим один из простых методов, который называется
методом выбора. Для примера будем рассматривать сортиров-
ку по возрастанию (неубыванию).
Предположим, что мы нашли минимальный элемент
массива. Где он должен размещаться в отсортированном
массиве?
Запишите в тетради фрагмент программы для поиска
номера минимального элемента массива.
21 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
22 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Выводы:
Выход за границы массива – это обращение к элементу масси-
ва с несуществующим индексом.
Линейный поиск – это перебор всех элементов массива до тех
пор, пока не будет найден нужный элемент или не закончится
массив.
Сортировка – это расстановка элементов списка (массива) в
заданном порядке. Данные сортируют для того, чтобы уско-
рить последующий поиск.
Для чисел обычно используют сортировку по возрастанию (не-
убыванию) или убыванию (невозрастанию).
Нарисуйте интеллект-карту этого параграфа.
Вопросы и задания
1. Что такое выход за границы массива? Что опаснее – чтение
или запись данных за границами массива?
2. На какой идее основан метод сортировки выбором?
3. Объясните, зачем нужен вложенный цикл в алгоритме сор-
тировки.
4. Как нужно изменить программу сортировки, чтобы элемен-
ты массива были отсортированы по убыванию?
Задачи
1. В переменных записаны значения a = 1, b = 2 и с = 3. Как
изменятся значения переменных после выполнении алго-
ритма:
c = a
b = a
a = c
Исправьте один символ так, чтобы получился правильный
алгоритм обмена значений переменных a и b.
2. Что произойдет с массивом [1, 2, 3, 4] (N = 4) при выполне-
нии следующего фрагмента программы:
for i in range(N-1):
A[i] = A[i+1]
23 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
24 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
25 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Темы сообщений:
а) «Сортировка методом пузырька»
б) «Сортировка методом вставки»
0 -1 0 1
1 -1 0 1
2 0 1 -1
Рис. 4.3.
Такие таблицы называются матрицами или двухмерными
массивами.
26 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Создание матрицы
Поскольку в Python нет массивов, то нет и матриц в клас-
сическом понимании. Для того, чтобы работать с таблицами,
используют списки. Двухмерная таблица хранится как «список
списков» – список, каждый элемент которого тоже представляет
собой список. Например, таблицу, показанную на Рис. 4.3, мож-
но записать так:
A = [[-1, 0, 1],
[-1, 0, 1],
[0, 1, -1]]
или в одну строчку:
A = [[-1, 0, 1], [-1, 0, 1], [0, 1, -1]]
Конечно, первый способ более нагляден.
Иногда нужно создать в памяти матрицу заданного разме-
ра, заполненную некоторыми начальными значениями, напри-
мер, нулями. Первая мысль – применить такой алгоритм, ис-
пользующий операцию повторения «*»:
N = 3
27 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
M = 2
# неверное создание матрицы!
row = [0]*M # создаём список-строку длиной M
A = [row]*N # создаём массив (список) из N строк
Однако этот способ работает неверно из-за особенностей
языка Python. Например, если после этого выполнить присваи-
вание
A[0][0] = 1
мы увидим, что все элементы столбца 0, то есть A[0][0],
A[1][0] и т.д. стали равны 1. Дело в том, что матрица – это
список ссылок на списки-строки (список адресов строк). При вы-
полнении оператора
row = [0]*M
транслятор создаёт в памяти одну единственную строку, а затем
следующий оператор
A = [row]*N
устанавливает на эту единственную строку все ссылки в массиве
A (Рис. 4.4).
A
0 0 1
1 1 0
2
Рис. 4.4.
Естественно, что когда мы меняет элемент с индексом 0 в
строке 0 (он выделен фоном на Рис. 4.4), меняются и все эле-
менты с индексом 0 во всех строках.
Для создания полноценной матрицы нам нужно как-то за-
ставить транслятор создать все строки в памяти как разные
объекты. Для этого сначала построим пустой список, а потом бу-
дем в цикле добавлять к нему (с помощью метода append) но-
вые строки, состоящие из нулей:
A = []
for i in range(N):
[Link]( [0]*M )
28 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
29 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
30 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
summa += A[i][j]
print(summa)
Эту задачу можно красиво решить в стиле Python:
summa = 0
for row in A:
summa += sum(row)
print(summa)
Здесь в цикле перебираются все строки матрицы A, каждая из
них по очереди записывается в переменную row. В теле цикла
сумма элементов очередной строки прибавляется к значению
переменной summa.
Квадратные матрицы
На практике (например, при решении шахматных задач)
часто приходится работать с квадратными матрицами, у кото-
рых количество строк и количество столбцов одинаковые.
Для квадратной матрицы используют понятия «главная
диагональ» (серые клетки на Рис. 4.6, а) и «побочная диагональ»
(Рис. 4.6, б). На Рис. 4.6, в выделена главная диагональ и все
элементы под ней.
а) б) в)
Рис. 4.6.
Главная диагональ – это элементы A[0][0], A[1][1], …,
A[N–1][N–1], то есть элементы, у которых номер строки равен
номеру столбца. Для перебора этих элементов достаточно одного
цикла:
for i in range(N):
# работаем с A[i][i]
Элементы побочной диагонали – это A[0][N–1], A[1][N–2],
…, A[N–1][0]. Заметим, что сумма номеров строки и столбца для
31 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
32 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Выводы:
Матрица — это прямоугольная таблица, составленная из эле-
ментов одного типа (чисел, строк и т.д.).
Каждый элемент матрицы имеет два индекса – номера строки
и столбца.
Главная диагональ квадратной матрицы – это элементы, у ко-
торых индекс строки равен индексу столбца.
Нарисуйте интеллект-карту этого параграфа.
Вопросы и задания
1. Сравните понятия «массив» и «матрица».
33 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Задачи
1. Напишите программу, которая находит максимальный эле-
мент на главной диагонали квадратной матрицы.
2. Напишите программу, которая находит максимальный эле-
мент матрицы и его индексы (номера строки и столбца).
3. *Напишите программу, которая находит минимальный из
чётных положительных элементов матрицы. Учтите, что та-
ких элементов в матрице может и не быть.
4. *Напишите программу, которая выводит на экран строку
матрицы, сумма элементов которой наибольшая.
5. *Напишите программу, которая выводит на экран столбец
матрицы, сумма элементов которого наименьшая.
6. Напишите программу, которая заполняет матрицу из N
строк и M столбцов нулями и единицами в шахматном по-
рядке.
7. Напишите программу, которая заполняет матрицу из N
строк и N столбцов нулями и единицами так, что все эле-
менты выше главной диагонали равны нулю, а остальные –
единице.
8. Напишите программу, которая заполняет матрицу из N
строк и N столбцов нулями и единицами так, что все эле-
менты выше побочной диагонали равны нулю, а осталь-
ные – единице.
9. *Заполните матрицу, содержащую N строк и M столбцов,
натуральными числами по спирали и змейкой, как на ри-
сунках:
34 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
а) 1 2 3 4 б) 1 3 4 9 в) 1 6 7 12
10 11 12 5 2 5 8 10 2 5 8 11
9 8 7 6 6 7 11 12 3 4 9 10
10. **Напишите программу, которая играет с человеком в кре-
стики-нолики на поле 3 3.
Темы сообщений:
«Игра "Жизнь"»
35 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
36 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Примеры
Рассмотрим алгоритмы выполнения различных операций с
массивом A длины N.
Пример 1. Вычислить сумму первых трёх элементов мас-
сива (при N 3).
Решение этой задачи содержит всего один оператор:
37 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Sum = A[0] + A[1] + A[2]
Этот алгоритм включает две операции сложения и одну опера-
цию записи значения в память, поэтому его сложность T(N) = 3
не зависит от размера массива вообще.
Вычислите количество операций (считая сравнения и
присваивание значений переменным) при выполнении
фрагмента программы:
a = 8
b = 15
if a < b:
c = 2*a + b
else:
c = 2*b + a
Пример 2. Вычислить сумму всех элементов массива.
В этой задаче уже не обойтись без цикла:
Sum = 0
for i in range(N):
Sum = Sum + A[i]
Здесь выполняется N операций сложения и N+1 операций запи-
си в память, поэтому его сложность T(N) = 2N + 1 возрастает ли-
нейно с увеличением длины массива.
Вычислите количество операций при выполнении фраг-
мента программы:
a = 0; b = 1
for i in range(N):
a = a + b*b
b = b + 1
Пример 3. Отсортировать все элементы массива по возрас-
танию методом выбора.
Напомним, что метод выбора предполагает поиск на каж-
дом шаге минимального из оставшихся неупорядоченных зна-
чений:
for i in range(N-1):
nMin = i
for j in range(i+1,N):
38 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
if A[j] < A[nMin]: nMin = j
c = A[i]
A[i] = A[nMin]
A[nMin] = c
Подсчитаем отдельно количество сравнений и количество пере-
становок. Количество сравнений элементов массива не зависит
от данных и определяется числом шагов внутреннего цикла:
N ( N 1) 1 2 1
Tc ( N ) ( N 1) ( N 2) ... 2 1 N N
2 2 2 .
Здесь использована формула для суммы первых членов ариф-
метической прогрессии.
На каждом шаге внешнего цикла происходит перестановка
двух элементов, общее количество перестановок равно
Tп(N) = N – 1, то есть сложность по перестановкам – линейная.
Определите количество операций при вычислении суммы
элементов квадратной матрицы A размером N N:
Sum = 0
for i in range(N):
for j in range(N):
Sum = Sum + A[i][j]
По результатам этих примеров можно сделать выводы:
простой цикл, в котором количество шагов пропорционально
N, – это алгоритм линейной сложности;
вложенный цикл, в котором количество шагов внешнего и
внутреннего цикла пропорционально N, – это алгоритм с
квадратичной функцией сложности.
39 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
T1
0 100 N
Рис. 4.7.
Обычно в теоретической информатике при сравнении ал-
горитмов используется их асимптотическая сложность, то
есть скорость роста количества операций при больших значени-
ях N.
Запись O(N) (читается «О большое от N») обозначает ли-
нейную сложность алгоритма. Это значит, что, начиная с неко-
торого значения N = N0, количество операций будет меньше,
чем c N, где c – некоторая постоянная:
T(N) c N для N N0.
При увеличении размера данных в 10 раз объем вычислений
алгоритма с линейной сложностью увеличивается тоже при-
мерно в 10 раз.
Пусть, например, T(N) 2N – 1, как в алгоритме поиска
суммы элементов массива. Очевидно, что при этом T(N) 2N
для всех N 1, поэтому алгоритм имеет линейную сложность.
Определите любые подходящие значения c и N0, такие что
T(N) c N для N N0, для алгоритмов с линейной асимп-
тотической сложностью:
а) T(N) = 2N – 8 б) T(N) = 7N + 5
Многие известные алгоритмы имеют квадратичную слож-
ность, O(N2). Это значит, что количество операций при больших
N не больше, чем c N2:
40 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
0 N0 N
Рис. 4.8.
Строго говоря, обозначение O(f(N)) определяет множество
всех алгоритмов, для которых количество операций T(N) растёт
не быстрее, чем f(N). Тогда, например, алгоритм с количеством
операций T(N) = N + 5 относится к классам O(N), O(N2) , O(N3) и
даже O(2N). Однако на практике выражение «алгоритм имеет
сложность O(N2)» чаще всего означает, что O(N2) – это наилуч-
шая асимптотическая оценка роста количества операций T(N),
41 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Выводы:
Временем работы алгоритма называется количество элемен-
тарных операций T, выполненных исполнителем.
Временная сложность алгоритма обычно зависит от объёма
исходных данных N, например, от размера массива.
Пространственная сложность – это объём памяти, необходимой
для работы алгоритма.
Простой цикл, в котором количество шагов пропорционально
N, – это алгоритм линейной сложности;
Вложенный цикл, в котором количество шагов внешнего и
внутреннего цикла пропорционально N, – это алгоритм квад-
ратичной сложности.
Алгоритм относится к классу O(f(N)), если найдется такая по-
стоянная с, что, начиная с некоторого N = N0 выполняется ус-
ловие T(N) c f(N).
Линейная сложность означает, что при увеличении размера
массива в K раз количество операций увеличивается примерно
в K раз.
Квадратичная сложность означает, что при увеличении раз-
мера массива в K раз количество операций увеличивается
примерно в K2 раз.
Нарисуйте интеллект-карту этого параграфа.
Вопросы и задания
1. Какие критерии используются для оценки качества алго-
ритмов?
2. Почему скорость работы алгоритма оценивается не време-
нем выполнения, а количеством элементарных операций?
43 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Задачи
1. Оцените асимптотическую сложность для алгоритмов:
а) вычисления произведения первого и последнего элемен-
тов массива;
б) вычисления суммы элементов первой половины массива;
в) нахождения минимального и максимального элементов
массива;
г) определения количества положительных элементов мас-
сива;
д) определения количества нулевых элементов квадратной
матрицы;
е) поиска всех делителей числа N.
Считайте, что массив содержит N элементов, а матрица име-
ет размеры N N.
2. Определите асимптотическую сложность алгоритмов, для
которых известно количество операций:
а) T(N) = 5 N+6 в) T(N) = 2 N3+100
б) T(N) = 3 N2+2 N+19 г) T(N) = 4 2N + 25 N18+8
3. Алгоритм обработки массива имеет асимптотическую слож-
ность O(N2), где N – длина массива. Во сколько раз увели-
чится время выполнения алгоритма, если длина массива
увеличится в 5 раз?
4. *Алгоритм обработки массива имеет асимптотическую
сложность O(2N), где N – длина массива. Как увеличится
время выполнения алгоритма, если длина массива увели-
чится на 5 элементов? в 5 раз?
Темы сообщений:
«Задача коммивояжёра»
44 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
46 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Задача
47 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Отладка программы
Простейший метод отладки программы – это вывод отла-
дочной информации. Рассмотрим этот способ на примере.
Программисту нужно было написать программу, которая
вычисляет корни квадратного уравнения ax2 + bx + c = 0. Он по-
спешил и написал программу так:
from math import sqrt
print( "Введите a, b, c:" )
a = float( input() )
b = float( input() )
c = float( input() )
48 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
D = b*b - 4*a*a
x1 = (-b + sqrt(D))/ 2*a;
x2 = (-b - sqrt(D))/ 2*a;
print( "x1={:.3}, x2={:.3}".format(x1, x2) )
Для вычисления квадратного корня здесь используется встро-
енная функция sqrt из модуля math.
Оказалось, что программа в некоторых случаях работает
верно (например, при a = 1, b = 2 и c = 1), а в других случаях –
неверно (например, при a = 1, b = –5 и c = 6).
Для того чтобы найти ошибку, нужно определить её воз-
можные причины. В нашем случае есть три варианта:
1) неверно вводятся данные;
2) неверно вычисляется дискриминант D = b2 – 4ac;
b D b D
3) неверно вычисляются корни x1 , x2 .
2a 2a
Добавим в программу две дополнительные команды для
вывода отладочной информации (они выделены фоном):
a = float( input() )
b = float( input() )
c = float( input() )
print( a, b, c )
D = b*b - 4*a*a
print( "D={}".format(D) )
С помощью этих команд мы
1) выведем значения коэффициентов a, b и с сразу после вво-
да;
2) выведем вычисленное значение дискриминанта.
Значения корней уравнения уже и так выводятся в конце рабо-
ты программы.
При вводе коэффициентов 1, –5 и 6 программа выводит
1.0 -5.0 6.0
D=21.0
x1=4.79, x2=0.209
По первой строчке видим, что ввод выполнен правильно –
именно такие числа мы вводили. А вот значение дискриминан-
49 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Документирование программы
К выпуску программы компания-разработчик должна под-
готовить документацию на программу. Руководство пользова-
теля (это наиболее важная часть документации) обычно содер-
жит:
назначение программы;
формат входных данных;
формат выходных данных;
примеры использования программы.
Для примера составим документацию на простую программу,
отладкой которой мы только что занимались.
Назначение программы: вычисление вещественных корней
квадратного уравнения ax2 + bx + c = 0.
50 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Выводы:
Этапы разработки программного обеспечения:
– постановка задачи
– построение модели
– разработка алгоритма и способа представления данных
– кодирование
– отладка
– тестирование
– документирование
– внедрение и сопровождение
При использовании метода проектирования «сверху вниз» (ме-
тода последовательного уточнения) задача разбивается на
подзадачи.
При использовании метода проектирования «снизу вверх»
разработка программы начинается с наиболее мелких подза-
дач, из которых основная программа затем собирается как из
кубиков.
Нарисуйте интеллект-карту этого параграфа.
51 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Вопросы и задания
1. Почему способы хранения данных и алгоритмы их обработ-
ки обычно разрабатываются одновременно?
2. Чем отличается тестирование от отладки?
3. Можно ли считать, что программа, успешно прошедшая тес-
тирование, не содержит ошибок?
4. Может ли произойти отказ в программе, в которой нет логи-
ческих ошибок?
5. Если программа плохо документирована, к каким последст-
виям это может привести?
6. Как вы думаете, почему важно сопровождение программы
после её сдачи заказчику?
7. Чем отличаются два подхода к проектированию программ:
«сверху вниз» и «снизу вверх»?
Задачи
1. Требуется написать программу, которая загружает массив
из файла и выводит отсортированный массив в другой
файл. Выделите подзадачи в этой задаче.
2. Требуется написать программу, которая загружает изобра-
жение из файла, выполняет его обрезку, преобразует из
цветного формата в чёрно-белый и выводит полученное изо-
бражение в другой файл. Выделите подзадачи в этой зада-
че.
3. Требуется написать программу для игры с человеком в
«крестики-нолики». Выделите подзадачи в этой задаче.
4. Отладьте программу для вычисления корней квадратного
уравнения. Учтите, что уравнение может не иметь вещест-
венных корней.
5. Используя образец, приведённый в тексте параграфа, со-
ставьте документацию на одну из написанных вами про-
грамм и предложите соседу ей воспользоваться. Вместе с
ним исправьте описание программы, если это потребуется.
52 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Темы сообщений:
а) «Структурное программирование»
б) «Парадигмы (стили) программирования»
53 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
§ 24. Процедуры
Ключевые слова:
процедура локальная переменная
параметр рекурсивная процедура
Простая процедура
Предположим, что в нескольких местах программы требу-
ется выводить на экран строчку из 10 знаков «–» (например, для
того чтобы отделить два блока результатов друг от друга). Это
можно сделать, например, так:
print( "----------" )
Конечно, можно вставить этот оператор вывода везде, где
нужно вывести такую строчку. Но это решение имеет два недос-
татка. Во-первых, строка из минусов будет храниться в памяти
много раз. Во-вторых, если мы задумаем как-то изменить эту
строку (например, заменить знак «–» на «=»), нужно будет ис-
кать эти операторы вывода по всей программе.
Для таких случаев в языках программирования предусмот-
рены процедуры. Посмотрим на программу с процедурой:
def printLine():
print( "----------" )
...
printLine()
...
printLine()
Многоточием в текстах программ будем обозначать некоторые
операторы, которые нас пока не интересуют.
Сначала в программе расположена процедура, выделенная
фоном. Она начинается со служебного слова def (от англ. de-
fine – определить). После имени процедуры записаны пустые
скобки (чуть далее мы увидим, что они могут быть и непустые!)
и двоеточие.
Все команды, входящие в тело процедуры, записываются с
отступом (так же, как и команды, входящие в тело цикла или
условного оператора).
55 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Процедура с параметром
Теперь представьте себе, что нужно выводить строки из
минусов разной длины (5, 10 и др). Конечно, можно сделать не-
сколько процедур, например, так:
def printLine5():
print( "-----" )
56 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
def printLine10():
print( "----------" )
Но так делать не нужно. Дело в том, что обе процедуры выводят
цепочки знаков «минус» (то есть, выполняют те же самые дейст-
вия!), только разной длины. Поэтому хочется использовать всего
одну процедуру, передавая ей нужную длину цепочки.
Процедуру printLine10 можно переписать, применив «ум-
ножение» строки на число (заменяющее, как и в математике,
многократное сложение):
def printLine10():
print( "-"*10 )
Эта процедура делает то же самое, что и первый вариант – вы-
водит 10 «минусов» подряд и переходит на новую строчку.
Чем будет отличаться процедура, рисующая 5 знаков
«минус», от последнего варианта процедуры printLine10?
Если мы хотим, чтобы длину строки можно было менять, в
процедуре вместо числа нужно использовать переменную. И
значение этой переменной необходимо как-то передать проце-
дуре. Оформляется это так:
def printLine( n ):
print( "-"*n )
Величина n называется параметром процедуры. Теперь в
круглые скобки в заголовке процедуры не пустые. В них запи-
сано имя параметра – специальной переменной, с помощью ко-
торой можно управлять работой процедуры.
Параметр — это переменная, от значения которой зависит ра-
бота подпрограммы. Имена параметров перечисляются в заго-
ловке подпрограммы.
Наша процедура printLine имеет один параметр, обозна-
ченный именем n – это длина строки из «минусов».
При вызове такой процедуры в скобках нужно записать
фактическое значение, которое присваивается переменной n
внутри процедуры:
printLine( 10 )
57 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
59 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Несколько параметров
Давайте немного улучшим процедуру: сделаем так, чтобы
можно было изменять не только длину строки, но и символы, из
которых она строится. Для этого добавим в процедуру ещё один
параметр, который можно назвать symbol:
def printLine( symbol, n ):
print( symbol*n )
Имена параметров в заголовке процедуры отделяются запятой.
Чем больше параметров у процедуры, тем больше разных
задач она может решать, но тем сложнее её понимать и легче
сделать ошибку. Поэтому не рекомендуется передавать в проце-
дуру больше 3-4 параметров.
Запишите в тетради полный текст процедуры
printLine, которая использует цикл с условием вместо
операции «умножения» символьных строк.
Что будет выведено на экран при выполнении фрагмента
программы
printLine( '-', 10 )
printLine( '=', 7 )
printLine( 'o', 5 )
Рекурсия
Составим процедуру, которая выводит на экран двоичную
запись натурального числа. Поскольку мы хотим использовать
процедуру для разных чисел, это должна быть процедура с па-
раметром:
def printBin( n ):
...
В теле процедуры должен быть алгоритм для перевода чис-
ла в двоичную систему. Один такой алгоритм мы знаем: нужно
делить число на 2, каждый раз выписывая остаток от деления,
пока не получится 0. На языке Python этот алгоритм можно за-
писать так:
62 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
while n != 0:
print( n % 2, end="" )
n = n // 2
Напомним, что именованный аргумент end, равный пустой
строке "", отключает переход на новую строку в конце работы
функции print (иначе все цифры будут выведены в столбик).
Проверьте вручную работу этого алгоритма для числа 6.
Удалось ли вам получить правильный ответ? Почему?
Проблема только в том, что первой мы получаем послед-
нюю цифру двоичной записи, поэтому остатки выводятся в об-
ратном порядке (не так, как нужно!).
Есть разные способы решения этой задачи, которые сводят-
ся к тому, чтобы запоминать остатки от деления (например, в
символьной строке) и затем, когда результат полностью полу-
чен, вывести его на экран. Однако можно применить ещё один
красивый подход. Идея такова: чтобы вывести двоичную за-
пись числа n, нужно сначала вывести двоичную запись числа
n // 2, а затем – его последнюю двоичную цифру, которая вычис-
ляется как n % 2.
Что же получилось? Прочитайте еще раз фразу, выделен-
ную курсивом в предыдущем абзаце. Выходит, что для того,
чтобы решить задачу для исходного числа, нужно предвари-
тельно решить ту же самую задачу для меньшего числа, n // 2.
Такой алгоритм очень просто программируется:
def printBin( n ):
printBin( n // 2 )
print( n % 2, end="" )
У нас получилось, что процедура printBin вызывает сама себя!
Такой приём в программировании называется рекурсией, а
процедура – рекурсивной.
Рекурсивная процедура — это процедура, которая вызывает
сама себя.
63 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Выводы:
Процедура – это вспомогательный алгоритм (подпрограмма),
решающий самостоятельную задачу, который может использо-
ваться несколько раз.
64 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Вопросы и задания
1. Зачем нужны процедуры?
2. Достаточно ли включить процедуру в текст программы, что-
бы она «сработала»?
3. Какие возможности появляются, когда в процедуру добав-
ляются параметры?
4. Как определить, что переменная – локальная?
5. Имеет ли смысл оформлять процедуру, если она вызывается
в программе только один раз? Обсудите достоинства и не-
достатки такого решения.
Задачи
1. Напишите процедуру, которая принимает два параметра:
символ c и натуральное число N, и выводит на экран тре-
угольник из символов c со стороной N. Например, при c = "o"
и N = 5 мы должны получить
o
oo
ooo
oooo
ooooo
2. Напишите процедуру, которая принимает два параметра –
W и H, – и рисует на экране рамку из точек, ширина кото-
65 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Темы сообщений:
а) «Рекурсия в природе и искусстве»
б) «Ханойские башни»
66 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
§ 25. Функции
Ключевые слова:
функция параметры
вызов функции рекурсивная функция
Примеры функций
Задача 1. Составить функцию, которая определяет наи-
большее из двух целых чисел.
Алгоритм определения наибольшего из двух чисел вы уже
знаете из курса 8 класса. Остаётся только «завернуть» его в
функцию. Например, так:
def Max( a, b ):
if a > b:
maximum = a
else:
maximum = b
return maximum
Одна функция может вызывать другую. Например, можно
составить функцию Max3, которая возвращает наибольшее из
трёх чисел, используя готовую функцию Max:
def Max3( a, b, c ):
return Max( Max(a,b), c )
Постройте функцию Max4, которая вычисляет наиболь-
шее из четырёх чисел, используя функцию Max. Приведите
два варианта решения задачи.
70 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
71 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
72 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Логические функции
Программисты часто используют логические функции, воз-
вращающие логические значения («да»/«нет», «истина»/«ложь»,
True/False). Такие функции полезны для того, чтобы опреде-
лять, успешно ли выполнена задача или обладают ли данные
каким-то свойством.
Мы напишем простую функцию, которая определяет чёт-
ность числа – возвращает значение «да» (в Python оно обознача-
ется как True), если число-параметр чётное, и «нет» (False), если
нечётное:
def Even( n ):
return (n % 2 == 0)
В правой части оператора return записано условие: ре-
зультатом функции будет «да» (True), если условие истинно, и
«нет» (False), если оно ложно. Можно было записать то же самое
иначе:
if n % 2 == 0:
return True
else:
return False;
но эта запись более длинная и опытные программисты так не
делают.
Запишите в развёрнутой форме возврат логического
значения из функции:
return (a > b + c)
Запишите в краткой форме возврат логического значения
из функции:
if a + b > 10:
return False
else:
return True
Результат, который возвращает логическая функция, мож-
но использовать во всех условиях как обычное логическое зна-
чение. Например, так:
73 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
if Even(a):
half = a // 2
или так:
count = 0
while Even(x):
x = x // 2
count += 1
Найдите значения переменных a и b, при которых в
результате работы этого фрагмента программы будет
выведено сообщение «Да!»:
if Even( a+3*b ):
print( "Да!" )
Найдите значение переменной a, при котором этот цикл
выполнится ровно 4 раза:
while Even( a ) and a > 5:
a = a // 2
Рекурсия
Вы уже знакомы с рекурсивными процедурами, которые
вызывают сами себя. Функции тоже могут быть рекурсивными,
в некоторых случаях это позволяет записать решение задачи
намного проще.
Рекурсивная функция — это функция, которая вызывает са-
ма себя.
Вернёмся к задаче вычисления суммы цифр числа. Можно
сформулировать алгоритм её решения так: сумма цифр числа N
равна значению последней цифры плюс сумма цифр числа, по-
лученного отбрасыванием последней цифры.
Вход: натуральное число N.
Шаг 1. d = N % 10
Шаг 2. M = N // 10
Шаг 3. s = сумма цифр числа M
Шаг 4. sum = s + d
Результат: sum.
74 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Итак, для того чтобы найти сумму цифр числа, нужно сложить
его последнюю цифру и сумму цифр другого числа, то есть вы-
полнить тот же самый алгоритм, только с другими исходными
данными (эта строка в записи алгоритма выделена фоном).
Получился рекурсивный алгоритм, в программе его можно за-
писать в виде рекурсивной функции:
def sumDigRec( N ):
if N == 0: return 0
d = N % 10
s = sumDigRec( N // 10 )
return s + d
Изучите текст функции и ответьте на вопросы:
зачем добавлен условный оператор в начале функции?
что произойдет, если удалить этот условный оператор?
как можно доказать, что для любого целого числа рекур-
сия обязательно закончится?
В рекурсивном варианте функции исчез цикл, поэтому
можно сделать вывод: рекурсия может заменить цикл. Верно и
обратное: любую рекурсивную функцию можно записать без ре-
курсии, с помощью циклов. Решение с помощью цикла (оно на-
зывается итерационным) обычно работает быстрее, чем рекур-
сивное, и требует меньше памяти. Однако рекурсивное решение
очень часто короче и проще для понимания.
Выводы:
Функция — это подпрограмма, которая возвращает результат
(число, строку символов и др.).
Вызов функции можно использовать в арифметических выра-
жениях и условиях так же, как и переменную того типа, кото-
рый возвращает функция.
75 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
Вопросы и задания
1. Чем функция отличается от процедуры?
2. Определите, какие распоряжения начальника можно счи-
тать вызовом процедуры, а какие – вызовом функции:
а) «Проводите Ивана Ивановича!»
б) «Принесите, пожалуйста, кофе!»
в) «Подготовьте годовой отчёт!»
г) «Постройте конуру для собаки!»
3. Как по тексту программы определить, значение какого типа
возвращает функция?
4. Сравните рекурсивное решение задачи о сумме цифр числа
и решение с помощью цикла. Какое из них вам больше нра-
вится? Обсудите этот вопрос в классе.
Задачи
1. Напишите функцию, которая вычисляет среднее арифмети-
ческое пяти целых чисел.
2. Напишите функцию, которая находит количество цифр в
десятичной записи числа.
3. Напишите функцию, которая находит количество единиц в
двоичной записи числа.
4. Напишите функцию, которая удаляет из символьной строки
все пробелы в начале строки и возвращает новую строку.
76 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
77 [Link]
07.04.2019
Информатика, 9 класс К.Ю. Поляков, Е.А. Еремин
78 [Link]