Другие языки программирования и технологии

Прошу объяснить как работает рекурсия в конкретном примере:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class trololo
{
public void srr(string str) { if (str.Length > 0) srr(str.Substring(1, str.Length - 1)); else return; Console.Write(str[0]); }
}
class Program
{
static void Main(string[] args)
{
string str = "Єто строка шиворот на выворот";
trololo ob = new trololo();
ob.srr(str);
Console.ReadLine();

}
}
}
Учусь.Привык понимать то что читаю это понять не могу. public void srr(string str) { if (str.Length > 0) srr(str.Substring(1, str.Length - 1)); else return; Console.Write(str[0]); } вырезает строку без первого и последнего символа пока не "исчезенет"а потом выводит первый символ каждого из вырезков(?)Вот что я понимаю.Но програма работает хотя не должна...Может я не чётко понимаю как работает метод Substring?спс за ответ
public string Substring(int startIndex, int length)

Сводка:
Извлекает подстроку из данного экземпляра. Подстрока начинается с указанной позиции знака и имеет указанную длину.

Параметры:
startIndex:
Позиция первого знака подстроки в данном экземпляре (с нуля) .

length:
Число символов в подстроке.

Возвращает:
Строка, эквивалентная подстроке длиной length, которая начинается с startIndex
в данном экземпляре, или System.String.Empty, если значение startIndex равно
длине данного экземпляра, а значение length равно нулю.

Исключения:
System.ArgumentOutOfRangeException:
Значение startIndex плюс length задает позицию вне пределов данного экземпляра. —
или — Значение параметра startIndex или length меньше нуля.

Строка из Main никуда не исчезает, просто при каждом рекурсивном вызове функции, размер принимаемой подстроки уменьшается на единицу. Это уменьшение результат смещения индекса. Когда размер строки равен нулю, функция возвращается в место вызова, в строке остался только символ конца строки, что и позволяет вызвать ещё раз и в качестве параметра передать целую строку. А подстрока по прежнему равна нулю и индекс равен нулю, теперь из целой каждый раз будет получаться подстрока с увеличением на один символ, и каждый новый символ будет иметь нулевой индекс. Он то и будет распечатан на экран. Дойдя до первого символа в строке, очередного вызова не случиться, так как символа начала строки нет.
Чтобы понять с какой позиции и как определяется обратный отсчёт, достаточно, в вашем случае, добавить в исходную строку ещё один символ, допустим, точку в конце. (Требуется чётное количество символов в строке. ) И станет всё ясно!
Главное понять, что метод srr() работает с целой строкой.

using System;

namespace ConsoleApplication1
{
class trololo
{
public void srr(string str)
{
if (str.Length > 0)
srr(str.Substring(1, str.Length - 2));
else return;
Console.Write(str[0]); // строка распечатается со средины
}
}
class Program
{
static void Main(string[] args)
{
string str = "Это строка шиворот на выворот. ";
trololo ob = new trololo();
ob.srr(str);
Console.ReadLine();
}
}
}
Артур Григорян
Артур Григорян
68 697
Лучший ответ
Хех. Не знаю шарпа, но мне кажется вот что:
Последний символ Субстринг не вырезает, и вот почему: индексация символов в строке начинается с нуля. То есть, если индексация с 1, то номер начала - 1, а номер конца равен длине строки.
В случае индексации с нуля (как в С, явно и в Шарпе) нужно из обоих чисел вычесть по 1, получается
Начало: 0
Конец: длина-1
Как работает рекурсия - функция берёт строку, отбирает первый (тьфу ты ж чёрт - нулевой) символ, зовёт "товарища", который делает всё то же самое.. . <рекурсия> какому-то товарищу ничего не остаётся и он просто уходит, никого не позвав, после этого каждый товарищ, увидев, как уходит "тот, кого он позвал", ставит отобранный символ на место. И они таким образом вылазят в обратном порядке.
Во-от.
если размер строки больше нуля (сиречь строка непустая)
то в функцию передаём строку без первого символа
функция получает строку (уменьшенную на один символ)

если размер строки больше нуля (сиречь строка непустая)
то в функцию передаём строку без первых двух символов
....
если строка нулевая - возвращаемся на уровень вверх
печатаем последний символ и возвращаемся на уровень вверх
печатаем предпоследний символ и возвращаемся на уровень вверх