- •Формальные языки записи алгоритмов
- •Трансляторы и интерпретаторы языков программирования
- •Зачем нужно уметь программировать?
- •Комментарии к коду
- •Комментарии к коду
- •Экзотические языки программирования Специальные, экзотические и эзотерические языки программирования
- •Эзотерические языки программирования
- •О языке Python
- •Рекомендуемая литература
- •Интерпретация и компиляция
- •Алгоритм работы простого интерпретатора:
- •Ввод-вывод в Python Ввод данных
- •Вывод данных
- •Установка Python и сред разработки
- •Установка интерпретатора
- •Установка интегрированной среды разработки
- •Cреда программирования wing ide
- •Ключевые слова и идентификаторы в Python Идентификаторы
- •Ключевые слова
- •Концепция присваивания
- •Функция определения длины строки в Python
- •Литералы строк в Python
- •Срезы строк в Python
- •Примеры срезов
- •Методы строк в Python
- •Методы find и rfind
- •Метод replace
- •Метод count
- •Работа с тестирующей системой
- •Задачи поиска, замены и удаления подстроки в строке в Python
- •Метод replace
- •Метод count
- •Удаление подстроки
- •Числа с плавающей точкой (вещественные)
- •Основные операции с вещественными числами
- •Логический тип (bool) в Python
- •Логические операции
- •Принцип условного исполнения
- •Условная инструкция в Python
- •Вложенные условные инструкции
- •Операторы сравнения
- •Логические операторы
- •Каскадные условные инструкции
- •Инструкция pass в Python
- •Инструкции управления циклом в Python
- •Цикл while в Python
- •Вывод числа с обратным порядком цифр и в заданной системе счисления
- •Тест простоты
- •Проверка простоты перебором делителей
- •Факторизация перебором делителей
- •Факторизация перебором делителей на python
- •Факторизация перебором делителей на pascal
- •Разложение числа на множители в Python
- •Алгоритм Евклида: Python
- •Проверка числа на простоту в Python
- •Функция range
- •Фильтрация потока чисел
- •Поиск числа в потоке на Python
- •Поиск максимального и минимального числа в потоке на Python
- •Генерация псевдослучайных чисел
- •Детерминированные генераторы
- •Обработка исключений
- •Генерация исключений
- •"Страхование" от ошибок
- •Функции в программировании
- •Важное дополнение
- •Как написать хорошую функцию
- •Преимущества структурного программирования
- •Без использования структурного программирования
- •С использованием структурного программирования
- •Задания
- •Данная программа ищет самый популярный фильм среди данных
- •Функции в Python
- •Вызов функции и возврат значения
- •Передача параметров в функцию
- •Примеры
- •Граф вызовов функций
- •Пример на языке си
- •Что вернет функция a() в место своего вызова?
- •В каком порядке будут напечатаны X() started и X() finished для a, b, c, d?
- •Стек вызовов
- •Области видимости переменных в Python
- •Правила видимости имен
- •Пример перекрытия областей видимости
- •Доступ на присваивание к нелокальным именам
- •Полиморфизм функций в Python
- •Контрольные вопросы
- •Решение
- •Решение
- •Математические функции в Python
- •Функции в библиотеке math
- •Степенные и логарифмические функции
- •Тригонометрические функции
- •Радианы в градусы и наоборот
- •Пример программы с математическими функциями
- •Кортежи в Python Кортежи в Python
- •Кортежи в логическом контексте
- •Присваивание нескольких значений за раз
- •Методы split и join для списка строк в Python
- •Списки в Python
- •Сортировка выбором
- •Пример сортировки выбором минимума на си
- •Пример сортировки выбором минимума на python
- •Пример сортировки выбором минимума на pascal
- •Сортировка методом пузырька
- •Реализация сортировки массива методом пузырька на языке python
- •Реализация сортировки массива методом пузырька на языке pascal
- •Модернизация сортировки методом пузырька
- •Случайное перемешивание массива в Python
- •Сортировка подсчетом
- •Пример сортировки подсчетом на python
- •Пример сортировки подсчетом на языке си
- •Пример сортировки подсчетом на языке pascal
- •Генерация псевдослучайных чисел
- •Детерминированные генераторы
- •Вычисление суммы натуральных чисел от 1 до n
- •Проверка строки на палиндромность
- •Суммирование списка
- •Наибольшее значение в списке
- •Числа фибоначчи
- •Быстрое возведение в степень
- •Ханойские башни
- •Ограничение на глубину рекурсии
- •Стиль программирования (для Python)
- •Основные правила pep 8: Форматирование
- •Комментарии
- •Функции
- •Работа с текстовыми файлами в Python открытие файла
- •Чтение данных из файла
- •Вывод данных в файл
- •Закрытие файла
- •Двумерные массивы в Python
- •Создание вложенных списков
- •Ввод двумерного массива
- •Пример обработки двумерного массива
- •Вложенные генераторы двумерных массивов
- •Генераторы таблиц
- •Вычисление произведения матриц
- •Многомерные списки в Python обработка и вывод вложенных списков
- •Создание двумерного списка
- •Ввод двумерного списка
- •Сложный пример обработки двумерной таблицы
- •Множества в Python
- •Создание множества
- •Изменение множества
- •Удаление элементов множества
- •Основные операции с множествами
- •Множества в логическом контексте
- •Множества
- •Задание множеств
- •Работа с элементами множеств
- •Перебор элементов множества
- •Операции с множествами
- •Словари (ассоциативные массивы) в Python
- •Когда нужно использовать словари
- •Создание словаря
- •Работа с элементами словаря
- •Перебор элементов словаря
- •Словари со смешанными значениями
- •Пример хранения списков в словаре
- •Пример дешифрации текста после алфавитной замены
- •Дан текст:
- •Итог всех замен:
- •Итог всех замен:
- •Окончательный вариант:
- •Рекурсивный перебор
- •Перебор всех подмножеств
- •Перебор всех k-элементных подмножеств
- •Перебор всех перестановок
- •Одномерное динамическое программирование: количество способов Задача о кузнечике
- •Рекурсивное решение
- •Пример на языке python
- •Пример на языке pascal
- •Нерекурсивное решение
- •Пример на языке python
- •Пример на языке pascal
- •Модификации задачи о кузнечике
- •Пример на языке python
- •Пример на языке pascal
- •Пример на языке python
- •Пример на языке pascal
- •Одномерное динамическое программирование: наилучший способ задача о кузнечике со стоимостями
- •Пример на языке python
- •Пример на языке pascal
- •Восстановление ответа
- •Пример программы на языке python:
- •Пример программы на языке pascal:
- •Пример программы на языке python:
- •Пример программы на языке pascal:
- •Пример программы на языке python
- •Пример программы на языке pascal:
- •Линейные задачи
- •Рекурсивный перебор
- •Перебор всех подмножеств
- •Перебор всех k-элементных подмножеств
- •Перебор всех перестановок
- •Сортировка слиянием
- •Быстрая сортировка Хоара: Python
- •Асимптотика алгоритма
- •Объектно-ориентированное программирование
- •Классы в Python
- •Метод init
- •Создание экземпляров
- •Переменные экземпляра
- •Плановая обработка ошибок при помощи исключений в Python
- •Обработка исключений
- •Генерация исключений
- •“Страхование” от ошибок
- •Юнит-тестирование
- •Тестирование как этап разработки программы
- •Виджеты
- •Происхождение термина «виджет»
- •Типовые элементы интерфейса
- •Модуль tkinter Что такое tkinter?
- •Класс Tk
- •Общее для всех виджетов
- •Методы виджетов
- •"Системные" методы
- •Пример, часы:
- •Пример:
- •Основные виджеты
- •Методы виджета
- •Упаковщики
- •Привязка событий
- •Изображения
- •Пошаговые инструкции
- •Математические функции в Python
- •Функции в библиотеке math
- •Степенные и логарифмические функции
- •Тригонометрические функции
- •Радианы в градусы и наоборот
- •Пример программы с математическими функциями
- •Массивы чисел в модуле math Массивы чисел
- •Векторы
- •Математические операции над векторами
- •Векторные функции
- •Использование списков
- •Основы Numerical Python
- •К слову, о срезах
- •Задание координат и значений функций
- •Векторизация
- •Визуализация функций в Matplotlib
- •Набор точек
- •Функция
- •Украшения
- •Несколько кривых
- •Маркеры
- •Дополнительные аргументы plot()
- •Сохранение файла
- •Гистограммы
- •Модуль os в Python
- •Текущий рабочий каталог
- •Работа с именами файлов и каталогов
- •Получение содержимого каталога
- •Получение сведений о файле
- •Получение абсолютных путей
- •Анализ аргументов командной строки в Python
- •Примеры без использования argparse
- •Использование библиотеки argparse
Реализация сортировки массива методом пузырька на языке pascal
type
massiv = array[1..1000] of longint;
var
a: massiv;
i, n: longint;
procedure bubbleSort(var a: massiv);
var
i, j: longint;
begin
for j := 1 to n - 1 do
for i := 1 to n - 1 do
if a[i] > a[i + 1] then
swap(a[i], a[i + 1]);
end;
begin
readln(n);
for i := 1 to n do
read(a[i]);
bubbleSort(a);
for i := 1 to n do
write(a[i], ' ');
end.
По структуре программы видно, что такая сортировка требует (N−1)(N−1) операций. То есть время работы программы можно оценить как O(n2).
Модернизация сортировки методом пузырька
Приведем пару соображений по оптимизации написанного кода. Представим себе, что у нас есть массив на два миллиона чисел, и мы уже сделали миллион проходов. Это значит, что как минимум миллион чисел в массиве уже стоят на своих законных местах в конце массива. Следовательно, нет никакого смысла проходить правую половину массива, потому что там никаких изменений точно уже не будет. Итак, если на первом проходе мы делаем N−1 сравнение, то на втором достаточно N−2, на третьем достаточно N−3 и так далее по мере увеличения количества чисел, которые стоят на своих местах. Таким образом кусочек программы, отвечающий за сортировку можно переписать так:
PYTHON:
def BubbleSort(A): for j in range(len(A)-1): for i in range(len(A)-1): if A[i] > A[i + 1]: A[i], A[i + 1] = A[i + 1], A[i]
PASCAL:
procedure bubbleSort(var a: massiv);
var
i, j: longint;
begin
for j := 1 to n - 1 do
for i := 1 to n - j do
if a[i] > a[i + 1] then
swap(a[i], a[i + 1]);
end;
Количество операций (а вместе с ним и время работы) нам удалось сократить вдвое. Хотя, следует признать, что оценка времени работы алгоритма все еще составляет O(N2).
Второе соображение для оптимизации метода простого обмена основано на таком утверждении: если за полный проход в массиве не сделано ни одной перестановки, то его можно считать отсортированным. Что значит «не сделано ни одной перестановки»? Это значит, что все пары соседних чисел расположены «правильно», то есть большее число идет позже меньшего, поэтому они в перестановках не нуждаются. Это позволяет значительно сократить время в случаях, когда более или менее повезло с исходными данными.
Например, в массиве 8, 1, 2, 3, 4, 5, 6 будет вообще достаточно одного прохода, чтобы вытолкнуть восьмерку на последнее место.
Существенных изменений в структуре программы не будет – как был двойной цикл, так и остался. Просто внешний цикл будет заменен на цикл с условием. Программа в этом случае может выглядеть, например, так:
PYTHON:
def BubbleSort(A): j = len(A) - 1 IsNotOrdered = True while IsNotOrdered: IsNotOrdered = False for i in range(0, j): if A[i] > A[i + 1]: A[i], A[i + 1] = A[i + 1], A[i] IsNotOrdered = True j -= 1
PASCAL:
procedure bubbleSort(var a: massiv);
var
i, j: longint;
isNotOrdered: boolean;
begin
isNotOrdered := true;
j := n - 1;
while isNotOrdered do
begin
isNotOrdered := false;
for i := 1 to j do
if a[i] > a[i + 1] then begin
swap(a[i], a[i + 1]);
isNotOrdered := true;
end;
dec(j);
end;
end;
Стоит заметить, что в худшем случае (а именно, если на входе дан массив, упорядоченный в другую сторону) время работы все равно будет составлять O(N2) и по количеству операций сравнения программа не будет отличаться от предыдущего примера.
Есть различные алгоритмы, построенные на основе пузырьковой сортировке. Например, в шейкерной сортировке внутренний цикл проходится поочередно слева направо, затем справа налево. А в сортировке Шелла элементы переставляются не соседние элементы, а элементы, отстоящие на большее расстояние, что позволяет быстрее перемещать элементы по списку, выполняя сразу несколько шагов.
Синхронная сортировка массивов
Возьмем два массива одинаковой длины, и отсортируем первый из них. При этом со значениями второго будем осуществлять ровно те же манипуляции. В результате значения второго массива останутся привязаны к исходным значениям первого.
def BubbleSort(A, B): for j in range(len(A) - 1, 0, -1): for i in range(0, j): if A[i] > A[i + 1]: A[i], A[i + 1] = A[i + 1], A[i] B[i], B[i + 1] = B[i + 1], B[i] A = [4, 2, 5, 1] B = ['Liza', 'Ivan', 'Andrey','Kolya'] BubbleSort(A, B)
С набором связанных значений удобней работать в форме кортежа. Тогда список сортируется по одному из значений, а кортеж перемещается как единое целое.
Кортеж — это неизменяемый список. Кортеж не может быть изменён никаким способом после его создания, т. е. Вы не можете добавить элементы к кортежу, нет методов append() или extend(), нельзя удалять элементы из кортежа. Кортежи не имеют методов remove() или pop(). Вы можете искать элементы в кортежи, поскольку это не изменяет кортеж. Вы также можете использовать оператор in, чтобы проверить существует ли элемент в кортеже.
Сортировка пузырьком по значению первого элемента в кортеже:
def BubbleSort(A): for j in range(len(A) - 1, 0, -1): for i in range(0, j): if A[i][0] > A[i + 1][0]: #сравниваем не кортежи целиком, а только ключи A[i], A[i + 1] = A[i + 1], A[i] A = [(4,'Liza'), (2,'Ivan'), (5,'Andrey'), (1,'Kolya')] BubbleSort(A)
Сортировка по двум параметрам с использованием сложного условия:
N = int(input()) A = [] for k in range(N): name, phone = input().split() A.append((name, int(phone))) for j in range(len(A)-1, 0, -1): for i in range(j): if A[i][0] > A[i+1][0] \ or A[i][0] == A[i+1][0] and A[i][1] > A[i+1][1]: A[i], A[i+1] = A[i+1], A[i] for k in range(N): name, phone = A[k] print(name, phone)
Устойчивость сортировок
Устойчивая сортировка не меняет взаимного расположения равных элементов.
Если элемент состоит только из одного ключа (т. е. значения, по которому и производится сортировка) то устойчивость сортировки не важна, но при сортировке списка, состоящего из кортежей (например, возраст и фамилия) в поддержании исходного порядка может быть смысл, так как равные по ключу элементы различны.
Устойчивые алгоритмы сортировки:
пузырьковая
вставкой
выбором
поразрядная
слиянием
Timsort
Неустойчивые алгоритмы сортировки:
быстрая сортировка Хоара
пирамидальная
Шелла
интроспективная
терпеливая
плавная
Сортировка выбором имеет как устойчивые, так и неустойчивые реализации.
Устойчивость сортировки всегда может быть достигнута путём удлинения исходных ключей, если включить в них информацию об первоначальном порядке значений.
