Львів
C
» » Рекурсивний Алгоритм: опис, аналіз, особливості та приклади

Рекурсивний Алгоритм: опис, аналіз, особливості та приклади

Сучасне розуміння рекурсії: визначення функціональності і звернення до неї ззовні і з цієї функціональності. Вважається, що рекурсія була народжена математиками: обчислення факторіала, нескінченні ряди, фрактали, неперервні дроби Проте, рекурсію можна знайти скрізь. Об'єктивні природні закони «вважають» рекурсію своїм основним алгоритмом і формою вираження (існування) не стільки предметів матеріального світу, скільки взагалі основним алгоритмом руху.
Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
Люди різних спеціальностей у різних галузях науки і техніки використовують рекурсивний алгоритм f (x), де x ~/= f (x)». Функція, що викликає сама себе, - сильне рішення, але формування і розуміння цього рішення, в більшості випадків, дуже непросте завдання.


В далекі часи застосовували рекурсію для збільшення палацового простору. Через систему спрямованих один на одного дзеркал, можна створити приголомшливі об'ємні просторові ефекти. Але чи так легко зрозуміти, як налаштувати ці дзеркала? А ще більш складно визначити, де знаходиться точка в просторі, відображена через декілька дзеркал.

Рекурсія, рекурсивні алгоритми: зміст і синтаксис

Завдання, яка формулюється повторенням послідовності операцій може бути вирішена рекурсивно. Простий алгоритм обчислення квадратного рівняння, скрипт наповнення веб-сторінки інформацією, читання файлу, передача повідомлення) не вимагає застосування рекурсії. Основні відмінності алгоритму, який допускає рекурсивне рішення:
  • є алгоритм, який потрібно виконати кілька разів;
  • алгоритм потребує даних, які змінюються кожного разу;
  • алгоритм не обов'язково повинен бути змінені кожен раз;
  • є фінальне умова: рекурсивний алгоритм - не нескінченний.
  • В загальному випадку, не можна стверджувати, що однократність виконання - обов'язкова умова відсутності підстав для рекурсії. Не можна також вимагати наявності обов'язкового фінального умови: у нескінченних рекурсий є своя сфера застосування.


    Рекурсивний Алгоритм: коли послідовність операцій виконується багаторазово, на даних, які змінюються кожного разу дає кожен раз новий результат.

    Формула рекурсії

    Математичне розуміння рекурсії та її аналог у програмуванні відмінні. Математики хоч і властиві ознаки програмування, але програмування - це математика набагато більш високого порядку.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    Добре написаний алгоритм - як дзеркало інтелекту його автора. Загальна формула рекурсія у програмуванні «f (x)», де «x ~/= f (x)» має, як мінімум, два варіанти інтерпретації. Тут «~» - подібність або відсутність результату, а «=» - наявність результату функції. Перший варіант: динаміка даних.
  • функція f(x)» має рекурсивний алгоритм і не змінюваний;
  • «x» і результат «f(x)» - кожен раз мають нові значення, результат «f(x)» є новим параметром «x» цієї функції.
  • Другий варіант: динаміка коду.
  • функція f(x)» має кілька алгоритмів, уточнюючих (аналізують) дані;
  • аналіз даних - одна частина коду і реалізація рекурсивних алгоритмів, виконують потрібну дію, - друга частина коду;
  • результату функції f(x)» - немає.
  • Відсутність результату - нормальне явище. Програмування - це не математика, тут результат не обов'язково повинен бути присутнім явно. Функція, що виконується рекурсивно, може просто робити парсинг сайтів і наповнювати базу даних, або створювати потрібні екземпляри об'єктів згідно вступнику вхідного потоку.

    Дані та рекурсія

    Програмування рекурсивних алгоритмів - це не обчислення факторіала, в якому функція отримує кожен раз дане, відмінне одиницю в меншу або більшу сторону - варіант реалізації залежить від переваги розробника. Не суть важливо, як вважати факторіал «8!», рухаючись від 012 або навпаки 876 Аналогічно обчислення математичної послідовності, фрактала або нескінченного ряду записується простою математичною формулою і, відповідно, алгоритмом, який суворо дотримується цієї формули. Обробка інформації - це «математика» зовсім іншого порядку. Рекурсивні функції та алгоритми тут оперують літерами, словами, фразами, реченнями та абзацами. Кожен наступний рівень використовує попередній. Вхідний потік даних аналізується по широкому спектру умов, але процес аналізу в цілому рекурсивен. Немає сенсу писати унікальні алгоритми на всі варіанти вхідного потоку. Повинен бути один функціонал. Тут рекурсивні алгоритми приклади того, як сформувати вихідний потік, адекватний вхідного. Це не результат, вступник на вхід рекурсивного алгоритму, але це бажане і необхідне рішення.

    Абстракція, рекурсія і ООП

    Об'єктно-орієнтоване програмування (ООП) і рекурсія - кардинально різні сутності, але вони ідеально доповнюють один одного. Абстракція не має ніякого відношення до рекурсії, але крізь призму ООП створює можливість реалізації контекстної рекурсії. Наприклад, йде розбір інформації та виділяються окремо букви, слова, фрази, речення та абзаци. Очевидно, розробник передбачить створення екземплярів об'єктів цих п'яти типів і запропонує рішення рекурсивних алгоритмів на кожному рівні.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    Між тим, якщо на рівні літер «немає сенсу шукати сенс», то на рівні слів з'являється семантика. Можна розділити слова на дієслова, іменники, прислівники, прийменники Можна піти далі і визначити відмінки. На рівні фраз семантика доповнюється знаками пунктуації та логікою поєднання слів. На рівні речень виявляється більш досконалий рівень семантики, а абзац можна розглядати як закінчену думку. Об'єктно-орієнтована розробка зумовлює успадкування властивостей і методів і пропонує починати ієрархію об'єктів зі створення абсолютно абстрактного предка. При цьому, поза всяким сумнівом, аналіз кожного нащадка буде мати рекурсивний характер і не надто відрізнятися на технічному рівні по багатьом позиціям (літери, слова, фрази і пропозиції). Абзаци, як закінчені думки, можуть виділятися з цього списку, але не суть. Важливо, що переважну частину алгоритму можна сформулювати на рівні абстрактного предка, уточнюючи її на рівні кожного нащадка даними і методами, що викликаються з абстрактного рівня. В даному контексті абстракція відкриває нові горизонти для рекурсії.

    Історичні особливості ООП

    ООП приходило у світ програм двічі, хоча деякі фахівці можуть виділити появу хмарних технологій і сучасні уявлення про об'єкти і класи, як новий виток в розвитку ІТ-технологій. Терміни «об'єкт» і «об'єктний» в сучасному контексті ООП, прийнято відносити до 50-х і 60-м рокам минулого століття, але асоціювати їх з 1965 роком і появою мов Simula, Lisp, Algol, Smalltalk. В ті часи програмування не відрізнялося особливим розвитком і не могло адекватно реагувати на революційні концепції. До боротьби ідей і стилів програмування (С/С++ та Pascal - в основному) ще було далеко, а бази даних ще тільки формувалися концептуально.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    В кінці 80-х і початку 90-х в Pascal з'явилися об'єкти і всі згадали про класи в С/С++ - це ознаменувало новий виток інтересу до ООП і саме тоді інструментальні засоби, насамперед мови програмування стали не тільки підтримувати об'єктно-орієнтовані ідеї, але і розвиватися відповідно їм. Природно, якщо раніше рекурсивні алгоритми представляли собою просто функції, які використовуються в загальному коді програми, то тепер рекурсія могла стати частиною властивостей об'єкта (класу), що в контексті спадкування надавало цікаві можливості.

    Особливість сучасного ООП

    Розвиток ООП спочатку декларувало об'єкти (класи) як сукупності даних і властивостей (методів). Фактично мова йшла про даних, що мають синтаксис і зміст. Але тоді не вдалося представити ООП, як інструмент управління реальними об'єктами.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    ООП перетворилося в інструмент управління об'єктами «комп'ютерної природи». Скрипт, кнопка, елемент меню, рядок меню, тег у вікні браузера - це об'єкт. Але не верстат, продукт харчування, слово, або пропозицію. Реальні об'єкти залишилися за межами об'єктно-орієнтованого програмування, а комп'ютерні інструменти придбали нове втілення. Внаслідок відмінностей популярних мов програмування, з'явилося безліч діалектів ООП. За семантикою вони практично еквівалентні, а їх орієнтація на інструментальну сферу, а не на прикладну, робить можливим виносити опис реальних об'єктів за межі алгоритмів і забезпечувати їх міжплатформною і міжмовне «існування».

    Стеки та механізми виклику функцій

    Механізми виклику функцій (процедур, алгоритмів) вимагають передачі даних (параметрів), повернення результату і запам'ятовування адреси оператора, який повинен отримати управління після завершення функції (процедури).
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    Зазвичай для цих цілей використовується стек, хоча мови програмування або сам програміст-розробник може передбачити найрізноманітніші варіанти передачі управління. Сучасне програмування припускає, що ім'я функції може бути не тільки параметром: воно може формуватися в процесі виконання алгоритму. Алгоритм також може бути створений у процесі виконання іншого алгоритму. Поняття рекурсивних алгоритмів, коли їх імена і тіла можуть бути визначені в момент утворення задачі вибору потрібного алгоритму) розширює рекурсивность не тільки на те, як щось зробити, але і хто саме це повинен зробити. Вибір алгоритму за його «осмисленому» імені - перспективно, але створює труднощі.

    Рекурсивность на множині функцій

    Не можна сказати, що рекурсивний алгоритм, коли він викликає себе і тільки. Програмування - не догма, а поняття рекурсивности - це не виключне вимогу викликати себе з тіла власного алгоритму. Практичні області застосування не завжди дають чисте рішення. Часто вихідні дані слід готувати, а результат рекурсивного виклику необхідно аналізувати в контексті всієї задачі (всього алгоритму) в цілому. Фактично, не тільки перед викликом рекурсивної функції, але і після її завершення, може або повинна бути викликана інша програма. Якщо з викликом особливих проблем немає: рекурсивна функція A() викликає функцію B(), яка щось робить і викликає A(), то відразу виникає проблема з поверненням управління. Відпрацювавши рекурсивний виклик, функція A() повинна одержати управління, щоб повторно викликати B(), яка знову її викличе. Повернення управління, як слід по черзі в стеку назад в B() - неправильне рішення. Програміст не обмежений у виборі параметрів і може комплектувати їх іменами функцій. Інакше кажучи, ідеальне рішення передати в A() ім'я B() і нехай сама A() робить виклик B(). В такому варіанті не буде проблем з поверненням управління, так і реалізація рекурсивного алгоритму буде прозорішим.

    Розуміння і рівень рекурсії

    Проблема розробки рекурсивних алгоритмів у тому, що потрібно мати уявлення про динаміку процесу. При використанні рекурсії в методах об'єктів, особливо на рівні абстрактного предка, з'являється проблема розуміння власного алгоритму в контексті часу його виконання.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    В даний час немає обмежень за рівнем вкладеності функцій і місткості стека в механізмах викликів, але є проблема розуміння: в який момент часу який рівень даних або яке саме місце в загальному алгоритмі виконало виклик рекурсивної функції і на якій кількості викликів самої себе, вона знаходиться. Існуючі інструменти налагодження часто безсилі підказати програмісту правильне рішення.

    Цикли і рекурсія

    Вважається, що циклічне виконання еквівалентно рекурсії. Дійсно, в деяких випадках, рекурсивний алгоритм можна реалізувати в синтаксисі умовних і циклічних конструкцій. Однак, якщо є чітке розуміння, що конкретна функція повинна бути реалізована за допомогою рекурсивного алгоритму, слід відмовитися від будь-якого зовнішнього варіанти використання циклу або умовних операторів.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    Сенс тут полягає в тому, що рекурсивне рішення у вигляді функції, що використовує саму себе буде закінченим, функціонально повним алгоритмом. Цей алгоритм вимагає від програміста зусиль при його створенні, розуміння динаміки роботи алгоритму, але він буде остаточним рішенням, яке не потребує зовнішнього управління. Будь-яка комбінація зовнішніх умовних і циклічних операторів не дозволить представити рекурсивний алгоритм у вигляді повноцінної закінченою функції.

    Консенсус рекурсії та ООП

    Практично у всіх варіантах розробки рекурсивного алгоритму виникає план розробити два алгоритму. Перший алгоритм формує список майбутніх об'єктів (примірників), а другий алгоритм являє собою власне рекурсивні функції. Кращим рішенням буде оформити рекурсію у вигляді одного властивості (методу), власне містить рекурсивний алгоритм, а всю підготовчу роботу винести в конструктор об'єкта. Рекурсивний алгоритм буде тільки тоді правильним рішенням, коли він працює тільки сам, без зовнішнього контролю і управління. Зовнішній алгоритм може тільки дати сигнал на роботу. Результатом цієї роботи має бути очікуване рішення, без зовнішньої підтримки. Рекурсія повинна бути завжди закінченим самостійним рішенням.

    Інтуїтивне розуміння і функціональна повнота

    Коли об'єктно-орієнтоване програмування стало стандартом де-факто, стало очевидно: для ефективного кодування слід змінити власне мислення. Програміст повинен перейти від синтаксису і семантики мови до динаміки семантики в ході виконання алгоритму. Характерна риса рекурсії: вона може бути застосована у всьому:
  • парсинг сайтів;
  • пошукові операції;
  • розбір текстової інформації;
  • читання чи створення документів MS Word;
  • вибірка або аналіз тегів
  • Характерна риса ООП: воно дає можливість описати рекурсивний алгоритм на рівні абстрактного предка, але передбачити в ньому звернення до унікальним нащадкам, кожен з яких володіє власною палітрою даних і властивостей.
    Рекурсивний Алгоритм: опис, аналіз, особливості та приклади
    Рекурсія - ідеальна, оскільки вимагає функціональної повноти свого алгоритму. ООП покращує якісні показники рекурсивного алгоритму, надаючи йому доступ до всіх унікальним нащадкам.