
3.3 Рекурсивні алгоритми обернення рядка
Нижче наведений ще один приклад рекурсії для виведення символьного рядка в зворотному порядку. Цей рядок задається як аргумент рекурсивного методу DisplayRev().
Приклад 5.
class RevStr
{
// Обернути рядок
public void DisplayRev(string str)
{
if (str.Length > 0)
DisplayRev(str.Substring(1, str.Length - 1)); //рекурсивний
else
return; //базовий випадок
Console.Write(str[0]);
}
}
class Program
{
static void Main()
{
string s = "Это тест";
RevStr rsOb = new RevStr();
Console.WriteLine("Исходная строка: " + s);
Console.Write("Перевернутая строка: ");
rsOb.DisplayRev(s);
Console.WriteLine();
Console.ReadKey();
}
}
}
Всякий раз, коли викликається метод DisplayRev (), в ньому відбувається перевірка довжини символьного рядка, представленого аргументом str. Якщо довжина рядка не дорівнює нулю, то метод DisplayRev() викликається рекурсивно з новим рядком, який менше початкового рядка на один символ. Цей процес повторюється до тих пір, поки цьому методу не буде переданий рядок нульової довжини. Після цього почнеться розкручуватися в зворотному порядку механізм усіх рекурсивних викликів методу DisplayRev(). При поверненні з кожного такого виклику виводиться перший символ рядка, представленого аргументом str, а у результаті увесь рядок виводиться в зворотному порядку.
Можна реалізувати іншу версію алгоритму обернення рядка.
Приклад 6. Алгоритм 2 обернення рядка
https://www.bestprog.net/ru/2019/01/21/recursion-examples-of-recursive-methods-functions-in-c-ru/
class Program
{
static string RString(string s1, int pos)
{
if (pos < s1.Length)
return s1[s1.Length - pos - 1].ToString() + RString(s1, pos + 1);
else
return ""; // пройдена вся строка - окончание рекурсивного процесса
}
static void Main(string[] args)
{
string s;
s = RString("abcd", 0); // s = "dcba"
Console.WriteLine(s);
s = RString("A", 0); // s = "A"
Console.WriteLine(s);
s = RString("", 0); // s = ""
Console.WriteLine(s);
s = RString("www.bestprog.net", 0); // s = "ten.gorptseb.www"
Console.WriteLine(s);
Console.ReadKey();
}
}
4. Переваги і недоліки рекурсії.
Переваги:
- при виклику рекурсивної функції не потрібно додатково зберігати тимчасові значення локальних змінних. Компілятор будує код рекурсивної функції таким чином, що тимчасові значення локальних змінних автоматично зберігаються при кожному рекурсивному виклику;
- в деяких випадках рекурсивні алгоритми виглядають більш просто і зрозуміло ніж ітераційні. Це пов'язано з тим, що в ітераційних алгоритмах для запам'ятовування проміжних результатів потрібно вводити додаткові змінні, які можуть ускладнити сприйняття ходу виконання самого алгоритму.
Недоліки:
- для заданого алгоритму рекурсивні виклики працюють повільніше ніж ітераційні. Це пов'язано з додатковими витратами системних ресурсів на неодноразові виклики методів;
- багаторазовий виклик методів може привести до переповнення системного стека. У цьому випадку середовище CLR згенерує відповідну виняткову ситуацію. Тому, важливо, щоб рекурсивний метод був розроблений таким чином, щоб в ньому оголошувалося мінімально можлива кількість параметрів і локальних змінних.
Контрольні запитання і завдання для самостійного виконання
1. Дати визначення рекурсії
2. Який алгоритм називається рекурсивним?
3. Яка різниця між прямою і непрямою рекурсією?
4. Які переваги використання рекурсії?
5. Якою конструкцією можна замінити рекурсію?
6. Що таке «глибина рекурсії»?
Ресурси
https://www.bestprog.net/ru/2019/01/21/recursion-examples-of-recursive-methods-functions-in-c-ru/