- •Формальные языки записи алгоритмов
- •Трансляторы и интерпретаторы языков программирования
- •Зачем нужно уметь программировать?
- •Комментарии к коду
- •Комментарии к коду
- •Экзотические языки программирования Специальные, экзотические и эзотерические языки программирования
- •Эзотерические языки программирования
- •О языке 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
procedure factorize(n: longint);
var
divisor: longint;
begin
divisor := 2;
while divisor * divisor <= n do
if n mod divisor = 0 then begin
n := n div divisor;
writeln(divisor);
end
else
inc(divisor);
if n <> 1 then
writeln(n);
end;
var
n: longint;
begin
readln(n);
factorize(n);
end.
Разложение числа на множители в Python
Основная теорема арифметики гласит, что разложение числа на простые множители существует и единственно. Решение этой задачи оформим в виде функции, которая по заданному числу n возвращает список его простых делителей с учетом кратности.
Алгоритм разложения числа на множители похож на алгоритм проверки числа на простоту. Будем проверять делимость данного числа n на натуральные числа подряд, начиная с числа 2. Если мы находим делитель числа n, то будем делить число n на данный делитель, пока число делится на него и добавлять делитель в список простых делителей.
Перебор также необходимо продолжать до n√. Если после окончания этого алгоритма число n не станет равно 1, то оставшееся значение также является простым, так как не делится ни на одно число, не превосходящее корня из оставшегося значения, поэтому его нужно добавить к списку простых делителей:
def Factor(n):
Ans = []
d = 2
while d * d <= n:
if n % d == 0:
Ans.append(d)
n //= d
else:
d += 1
if n > 1:
Ans.append(n)
return Ans
Сложность такого алгоритма, как и сложность алгоритма проверки числа на простоту, O(n√).
Алгоритм Евклида: Python
Рассмотрим задачу нахождения наибольшего общего делителя двух натуральных чисел. Постановка задачи — даны два натуральных числа a и b, необходимо найти такое наибольшее число d, которое является делителем каждого из этих чисел.
Задачу можно решать разными способами. Наивный алгоритм — будем перебирать все числа от 1 до min(a,b), будем проверять делимость чисел a и b на проверяемое число, выберем наибольшее число, на которое делятся и a, и b. Такой алгоритм будет имеет сложность O(min(a,b)).
Можно оптимизировать перебор, например, перебирать не все числа до min(a,b), а только делители одного из чисел (a или b). Это можно организовать перебирая числа до min(a,b)−−−−−−−√, если использовать идеи, аналогичные оптимизации алгоритма проверки числа на простоту, то есть алгоритм будет иметь сложность O(min(a,b)−−−−−−−√).
Гораздо более эффективно можно решить эту же задачу, если использовать алгоритм Евклида. Он основан на следующем свойстве (обозначим наибольший общий делитель чисел a и b как НОД(a, b)):
НОД(a, b) = НОД(a - b, b)
Свойство легко доказать, если заметить, что любой общий делитель чисел a и b также является общим делителем чисел a - b и b, и наоборот, т. е. для пар чисел (a, b) и (a - b, b) совпадают множества общих делителей, и, значит, и наибольший общий делитель.
Это позволяет написать рекурсивный алгоритм (название gcd есть аббревиатура от Greatest Common Divisor):
def gcd(a, b): if a == 0 or b == 0: return max(a, b) else: if a > b: return gcd(a - b, b) else: return gcd(a, b - a)
Этот алгоритм использует указанные рекуррентные соотношения до тех пор, пока одно из чисел не станет равно 0 (иногда используют другое условие окончания алгоритма — числа a и b станут равны), в этом случае возвращается значение другого числа.
Этот же алгоритм можно записать при помощи цикла while, без рекурсии:
def gcd(a, b): while a != 0 and b != 0: if a > b: a = a - b else: b = b — a return max(a, b)
Записанный в таком виде алгоритм неэффективен, так как многократно использует вычитания. Например, если взять a=10∗∗9+2, b=2, то алгоритм выполнит 500 миллионов вычитаний для получения вполне очевидного результата. Чтобы оптимизировать алгоритм необходимо понять, что многократное вычитание из большего числа меньшего закончится на числе, которое является остатком от деления двух первоначальных чисел. То есть в каждом из этих алгоритмов можно заменить операцию вычитания на взятие остатка:
def gcd(a, b): if a == 0 or b == 0: return max(a, b) else: if a > b: return gcd(a % b, b) else: return gcd(a, b % a)
или
def gcd(a, b): while a != 0 and b != 0: if a > b: a = a % b else: b = b % a return max(a, b)
Но алгоритм Евклида можно записать и еще проще. Давайте будем считать, что a≥b. Тогда после замены a=a%b результат этой операции станет меньше чем b, то есть теперь a<b. Чтобы вернуть свойство a≥b нужно поменять a и b местами, что удобно делать при помощи кортежей:
def gcd(a, b): if b == 0: return a else: return gcd(b, a % b)
или
def gcd(a, b): while b != 0: a, b = b, a % b return a
Таким образом, в этом алгоритме поддерживается два инварианта: a≥b и НОД(a,b) не меняется. Несложно заметить, что алгоритм будет корректно работать и в случае, когда a<b, тогда на первом же шаге значения a и b будут просто поменяны местами.
Можно показать, что наибольшее количество операций алгоритм Евклида будет выполнять, когда на вход ему даны два числа, являющиеся соседними членами ряда Фибоначчи, то есть ряда 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181 и т. д. Известно, что n-й член последовательности Фибоначчи можно вычислить по формуле
Fn=(1+5√2)n−(1−5√2)n5√, то есть Fn≈15√(1+5√2)n . Таким образом, сложность алгоритма Евклида: O(logmin(a,b)).
