
- •Основні положення теорії алгоритмів та її застосування
- •Введення до теорії алгоритмів
- •Загальні риси алгоритмів
- •Машина Поста
- •Машина т’юринга
- •Основи лямбда-числення та функціонального програмування
- •Теза Черча-т’юринга про алгоритмічну розв’язність задачі
- •Проблема розв’язності (зависання)
- •Алгоритмічно нерозв’язні задачі
- •Проблема відсутності загального методу вирішення задачі
- •Проблема інформаційної невизначеності задачі
- •Проблема логічної нерозв’язності задачі
- •Побудова машини т’юринга для обчислення деяких простих функцій
- •Введення до оцінки складності алгоритмів
- •Визначення порядку складності алгоритму
- •Оптимізація алгоритмів
- •Структури даних в алгоритмічній мові програмування
- •Визначення алгоритмічної мови програмування
- •Базові елементи сучасної мови програмування: типи даних; екземпляри даних; вирази; оператори; функції; класи.
- •Поняття типу даних
- •Прості типи: числові; символьні; логічні.
- •Тип даних рядок
- •Структуровані типи даних: масиви, записи, множини
- •Типи даних за значенням і за посиланням
- •Сумісність типів та перетворення між типами даних
- •Екземпляри даних: змінні, константи
- •Видимість даних
- •Управління ходом виконання та структурування програм в алгоритмічній мові програмування
- •Вирази, операнди та операції
- •Основні операції: арифметичні; логічні; бульові; з використанням рядків
- •Поняття оператора
- •Прості оператори: присвоювання; виклику функції
- •Оператори управління ходом виконання: розгалуження; вибору; цикли; переходу
- •Структурування програм: функції та класи
- •Параметри функцій: вхідні, результуючі.
- •Рекурсивні функції
- •Файли: текстові, бінарні
- •Алгоритми чисельних методів, апроксимації функцій, інтегрування та вирішення рівнянь з одним невідомим
- •Чисельні методи
- •Особливості вирішення задач чисельними методами, точність та коректність рішень
- •Апроксимації функцій: лінійна інтерполяція; інтерполяційний многочлен Ньютона.
- •Чисельне інтегрування: метод трапецій; метод Сімпсона; метод Сімпсона з оцінкою погрішності.
- •Вирішення рівнянь з одним невідомим: метод простих ітерацій; метод Ньютона; метод парабол.
- •Алгоритми вирішення системи лінійних рівнянь, пошуку екстремуму функції
- •Вирішення системи лінійних рівнянь методом Гауса
- •Пошук екстремуму функцій одної змінної: метод золотого перетину; метод парабол.
- •Пошук екстремуму функцій багатьох змінних: метод координатного спуску; метод найскорішого спуску.
- •Алгоритми обробки масивів
- •Визначення масивів
- •Операції над масивами
- •Упорядкування масивів: сортування вибором; сортування вставкою; бульбашкове сортування; сортування методом Шелла; метод швидкого сортування.
- •Вибір методів сортування
- •Пошук в упорядкованих масивах методом половинного поділу, інтерполяційним методом
- •Застосування індексів для пошуку у невпорядкованих даних
- •Алгоритми обробки даних на основі списків та дерев
- •Визначення списку
- •Види списків: незалежні списки, однозв’язані списки; двозв’язані списки; кільцеві списки; упорядковані списки
- •Основні операції над списками: включення елементу до списку; видалення елементу; перехід між елементами; ітератор для списку
- •Упорядкування та пошук в списках
- •Похідні структури даних: черга, стек, дек
- •Визначення дерева
- •Впорядковані дерева
- •Бінарні дерева
- •Основні операції з бінарними деревами: включення елементу; видалення елементу; обхід дерева
- •Балансування дерева
- •Алгоритми обробки текстових даних на основі регулярних виразів
- •Введення до теорії кінцевих автоматів
- •Графічне представлення кінцевих автоматів
- •Використання кінцевого автомату: синтаксичний аналіз.
- •Реалізація синтаксичного аналізу файлу з розділяючими комами
- •Детерміновані та недетерміновані кінцеві автомати
- •Регулярні вирази
- •Форма Бекуса-Наура для запису регулярних виразів
- •Синтаксичний аналіз регулярних виразів
- •Компіляція регулярних виразів
- •Інструменти для спрощення роботи з регулярними виразами
- •Зіставлення рядків з регулярними виразами.
- •Алгоритми систем числення
- •Введення до систем числення
- •Двійкова система числення
- •Шістнадцяткова система числення
- •Системи числення з нетрадиційними основами
- •Перетворення між різними системами числення
- •Арифметика чисел з плаваючою комою
- •Точність операцій з плаваючою комою
- •Арифметика великих чисел
- •Алгоритми криптографії та хешування
- •Значення випадкових чисел у програмуванні
- •Алгоритми генерації рівномірно розподілених псевдовипадкових чисел
- •Перевірка якості випадкових чисел
- •Кодування з виправленням помилок
- •Стиснення даних
- •Стиснення даних зі словником
- •Алгоритм стиснення даних Лемпела-Зіва
- •Введення до криптографії
- •Елементи теорії порівнянь
- •Шифрування за допомогою випадкових чисел
- •Створення таємного ключа по Діффі-Хеллману
- •Система rsa
- •Алгоритми цифрового підпису
- •Введення до хешування
- •Функції хешування
- •Проста функція хешування рядків
- •Функції хешування з використанням рандомізації
- •Вирішення конфліктів за допомогою лінійного зондування
- •Псевдовипадкове зондування
- •Подвійне хешування
Структурування програм: функції та класи
Для поділу коду програм на фрагменти з метою забезпечення повторного виклику, а також спрощення розробки, розуміння і збільшення наглядності, використовується підпрограми – іменовані блоки коду, які можуть бути викликані всередині операторів.
Підпрограми, які не повертають результат у точці виклику називаються процедурами і не можуть бути складовими виразів, а ті, які повертають, називаються функціями і можуть бути складовими виразів.
У сучасних об’єктно-орієнтованих мовах програмування будівельним блоком програм є більш комплексна і цілісна абстракція – клас, який являє собою поєднання коду і даних.
Підпрограми, які задекларовані всередині класу, називаються методами.
У мові програмування C# усі підпрограми декларуються в рамках класу, тому всі вони є методами.
Параметри функцій: вхідні, результуючі.
Повернення значень
Приклад:
Приклади повернення значення
Повернення об’єкту
Використання return для void-методів
Return може використовуватись для виходу із таких методів:
Формальні параметри:
Параметри за значенням
Виділення пам’яті для параметрів за значенням
Параметри за посиланням
Приклад використання параметрів за посиланням
Управління пам’яттю при використанні параметрів за посиланням
Параметри, які повертають значення
Приклад використання параметрів, які повертають значення
Управління пам’яттю при використанні параметрів, які повертають значення
Масиви параметрів
Варіанти виклику:
Рекурсивні функції
Рекурсія – дуже поширений у програмуванні підхід, який передбачає можливість виклику алгоритмом самого себе проте з іншими параметрами.
Вкладеність таких викликів може бути досить великою, проте в певний момент часу вона має припинитися і результат повертається (чи продовжуються обчислення) по ланцюгу рекурсивних викликів.
Основні переваги рекурсії:
рекурсія наглядна і зручна для представлення вирішення певних задач;
деякі структури природного чи штучного походження є рекурсивними за своєю сутністю;
деякі задачі є рекурсивними за своєю природою, зокрема рекурсія є окремим випадком декомпозиції – поділу однієї складної задачі на декілька простіших.
Приклади рекурсії
1. Натуральні числа:
1 – натуральне число;
ціле число, яке йде за натуральним, є натуральним числом.
2. Пісенька:
У попа був собака, він її любив
Вона з'їла шматок м'яса, він її убив
У землю закопав,
Напис написав:
«У попа був собака, він її любив
Вона з'їла шматок м'яса, він її убив
У землю закопав,
Напис написав:
«У попа був собака, він її любив
Вона з'їла шматок м'яса, він її убив
У землю закопав,
Напис написав:
…
Рекурсивне задання математичних функцій
Рекурсивно визначена функція містить у своєму визначенні посилання на саму цю функцію.
Розглянемо приклад визначення факторіалу.
Факторіал N:
N! = 1 × 2 × 3 × … × (N – 1) × N.
Рекурсивне визначення факторіалу:
N! = N × (N-1)!
Додатково:
0! = 1.
Числа Фібоначчі: елементи числової послідовності, в якій кожен наступний елемент дорівнює сумі двох попередніх:
FN = FN-1 + FN-2, де N ≥ 2, F0 = F1 = 1.
Приклад: 1, 1, 2, 3, 5, 8…
3. Поширені рекурсивні алгоритми
Бінарний пошук
Процедури обходу дерева
Фрактали – нескінченна самоподібна геометрична фігура, кожен фрагмент якої повторюється при зменшенні масштабу.
Задача про Ханойські вежі:
В одному з буддійських храмів ченці вже тисячу років займаються перекладанням кілець. Вони розташовані трьома пірамідами, на яких нанизані кільця різних розмірів. У початковому стані 64 кільця були нанизані на першу піраміду й упорядковані по розмірі. Ченці повинні перекласти всі кільця з першої піраміди на другу, виконуючи єдину умову - кільце не можна покласти на кільце меншого розміру. При перекладанні можна використовувати всі три піраміди. Ченці перекладають одне кільце за одну секунду. Як тільки вони закінчать свою роботу, наступить кінець світу.
Рекурсивний алгоритм обчислення факторіалу
using System;
using System.Collections.Generic;
using System.Text;
namespace Factorial
{
class Program
{
public static long fact(long n)
{
if (n == 0)
{
return 1;
}
else
{
return n * fact(n - 1);
}
}
static void Main(string[] args)
{
for (int i = 0; i <= 20; i++)
{
Console.WriteLine("{0}! = {1}", i, fact(i));
}
Console.ReadLine();
}
}
}
Алгоритм Евкліда для знаходження найбільшого спільного дільника
Число n є дільником числа m, якщо число m ділиться на число n без остачі.
Дільники числа 18: 1, 2, 3, 6, 9, 18.
Дільники числа 24: 1, 2, 3, 4, 6, 12, 24.
Найбільший спільний дільник чисел 18 та 24 це 6.
Скорочено: НСД (18, 24) = 6.
НСД (m, n) це найбільше з чисел на яке діляться і m і n.
Два числа m та n називаються взаємно простими, якщо їх НСД (m, n)=1. Наприклад, НСД(9, 16)=1.
Алгоритм Евкліда дозволяє знайти НСД двох натуральних чисел.
Суть алгоритму Евкліда – два числа порівнюють, та з більшого віднімають менше до тих пір, поки числа не стануть рівними. Число, якому вони стануть рівними і є їх найбільший спільний дільник.
using System;
using System.Collections.Generic;
using System.Text;
namespace Example
{
class Program
{
public static int nsd(int m, int n)
{
if (m == n)
{
return m;
}
else
{
if (m > n)
{
return nsd(m - n, n);
}
else
{
return nsd(n - m, m);
}
}
}
static void Main(string[] args)
{
Console.WriteLine(nsd(873435, 21345).ToString());
Console.ReadLine();
}
}
}
6. Рекурсивний алгоритм для обчислення чисел Фібоначчі
using System;
using System.Collections.Generic;
using System.Text;
namespace Example
{
class Program
{
public static long Fibonacci(long N)
{
if ((N == 1) | (N == 0))
{
return 1;
}
else
{
return Fibonacci(N - 1) + Fibonacci(N - 2);
}
}
static void Main(string[] args)
{
for (int i = 0; i <= 30; i++)
{
Console.WriteLine("{0}, {1}", i, Fibonacci(i));
}
Console.ReadLine();
}
}
}