Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
1

Как работает рекурсия?

13.08.2016, 22:44. Просмотров 772. Ответов 20
Метки нет (Все метки)

Помогите разобраться, не понимаю до конца как работает рекурсия в связке с субстринг...
Вопрос: Почему при условии if (str.Length > 1) не выводит последнею букву???
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Substring
{
    class Rek
    {
        public void DisplayReverse(string str)
        {
            if (str.Length > 0) ///При длине строки в 1-цу, 2-ой аргумент сабстринг будет равен 0
                DisplayReverse(str.Substring(1, str.Length - 1)); 
            else
                return;
            Console.Write(str[0]);///Как я думал (неправильно), первый вывод в рекурсии должен произойти при длине строки в 
                                  /// в один символ. Почему при условии if (str.Length > 1) не выводит последнею букву??? 
 
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            string str = "This is a";
            Console.WriteLine(str.Substring(1, str.Length - 1));
            Console.WriteLine(str[0]);
            Console.WriteLine(str.Substring(1, str.Length - 9));
            Console.WriteLine("Lengh is "+ (str.Length-9));
            Console.WriteLine(str[0]);
            char c = str[0];
            Console.WriteLine("Char c="+c);
            string f = "F";
            ////Console.WriteLine("String F is Substringed from 1 to 0(1-1) "+f.Substring(1, str.Length - 1)); не работает по
 //////понятным причинам
            Rek d = new Rek();
            Console.WriteLine("\n String is\n" + str + "\nReversed string is ");
            d.DisplayReverse(str);
            Console.ReadKey();
        }
    }
}

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.08.2016, 22:44
Ответы с готовыми решениями:

Рекурсия: как это работает
Здравствуйте. Помогите, пожалуйста, понять, как работает рекурсия, не могу...

Ряд Фибоначчи. Объясните как можно популярнее как работает рекурсия
По возможности максимально подробно расскажите про рекурсию public int...

Рекурсия: Объясните как работает функция получения НОДа
static int NOD(int a, int b) { if (b == 0) ...

Рекурсия, что работает не так?
. сумму чисел: 1+2^4+3^4+⋯+n^4. Указание: полученный результат сравнить с...

Рекурсия. Как вернуть 0?
Задача в том чтобы вводить n количество чисел, если введен 0 - то вывести...

20
EveKS
457 / 404 / 166
Регистрация: 19.04.2016
Сообщений: 1,604
Завершенные тесты: 7
13.08.2016, 23:51 2
ValeriiK,
C#
1
2
3
4
5
6
7
8
        public void DisplayReverse(string str)
        {
            if (str.Length > 0)
            {
                Console.Write(str[str.Length - 1]);
                DisplayReverse(str.Substring(0, str.Length - 1));
            }
        }
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 12:21  [ТС] 3
EveKS, мой код рабочий, он взят из учебника Шилдта, а Ваш код не работает (вывод только первой буквы в слове), проверьте...
Задам вопрос по другому: я не понимаю, почему в условие if (str.Length > 0) работает без ошибок, а при - if (str.Length > 1) не выводит последнею букву???
В комментах у меня есть пояснения, посмотрите
0
EveKS
457 / 404 / 166
Регистрация: 19.04.2016
Сообщений: 1,604
Завершенные тесты: 7
14.08.2016, 12:46 4
ValeriiK,
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
         static void Main(string[] args)
        {
            new Program().DisplayReverse("Проверяю"); // юяреворП
            Console.ReadKey(false);
        }
        public void DisplayReverse(string str)
        {
            if (str.Length > 0)
            {
                Console.Write(str[str.Length - 1]);
                DisplayReverse(str.Substring(0, str.Length - 1));
            }
        }
Добавлено через 6 минут
ValeriiK,
C#
1
2
 int length = "Слово".Length; //5
int length = "C".Length; //1
Т.е. одна буква имеет длинну 1.
C#
1
if (str.Length > 1)
ValeriiK,
Цитата Сообщение от ValeriiK Посмотреть сообщение
он взят из учебника Шилдта
Надо не брать пример а читать, в нем понятно описано как работает рекурсия.
C#
1
DisplayReverse(str.Substring(1, str.Length - 1)
Тут мы вызываем:
C#
1
public void DisplayReverse(string str)
Substring()

ValeriiK, str.Substring(0, str.Length - 1) - в моем примере!
0
kolorotur
Эксперт .NET
10692 / 8854 / 2215
Регистрация: 17.09.2011
Сообщений: 15,222
Завершенные тесты: 1
14.08.2016, 12:58 5
Цитата Сообщение от ValeriiK Посмотреть сообщение
Почему при условии if (str.Length > 1) не выводит последнею букву?
Потому что отработает блок else, который завершает метод, не доходя до вывода буквы.
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 13:05  [ТС] 6
EveKS, еще раз повторяю Ваш код не переворачивает строку, а выводит только первую букву
0
EveKS
457 / 404 / 166
Регистрация: 19.04.2016
Сообщений: 1,604
Завершенные тесты: 7
14.08.2016, 13:06 7
C#
1
2
3
4
5
if (str.Length > 0) ///При длине строки в 1-цу, 2-ой аргумент сабстринг будет равен 0
                DisplayReverse(str.Substring(1, str.Length - 1)); 
            else
                return;
            Console.Write(str[0]);
Цитата Сообщение от kolorotur Посмотреть сообщение
Потому что отработает блок else, который завершает метод, не доходя до вывода буквы.
ValeriiK, Вот именно поэтому я убрал эту часть кода
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 13:07  [ТС] 8
kolorotur, при 1 букве в строке это условие (str.Length > 1) завершает рекурсию и далее должно вывести эту букву. Почему оно не работает, а работает при условии (str.Length > 0)?
0
EveKS
457 / 404 / 166
Регистрация: 19.04.2016
Сообщений: 1,604
Завершенные тесты: 7
14.08.2016, 13:09 9
ValeriiK, надо учиться копипастить =)). А мой код работает верно.
Постораюсь еще раз обратить внимание на отличия моего кода от не моего:
str.Substring(0, str.Length - 1) //мой
str.Substring(1, str.Length - 1) //не мой
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 13:10  [ТС] 10
EveKS, а смысл? если ваш код не работает?
0
EveKS
457 / 404 / 166
Регистрация: 19.04.2016
Сообщений: 1,604
Завершенные тесты: 7
14.08.2016, 13:11 11
C#
1
2
3
4
5
           if (str.Length > 0) ///При длине строки в 1-цу, 2-ой аргумент сабстринг будет равен 0
                DisplayReverse(str.Substring(1, str.Length - 1)); 
            else
                return;
            Console.Write(str[0]);
Цитата Сообщение от ValeriiK Посмотреть сообщение
Почему оно не работает, а работает при условии (str.Length > 0)?
Цитата Сообщение от kolorotur Посмотреть сообщение
Потому что отработает блок else, который завершает метод, не доходя до вывода буквы.
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 13:13  [ТС] 12
EveKS, попробую зайти с другой стороны - я не просил редактировать код Шилдта, а - объяснить почему он работает так, а не иначе...
0
kolorotur
Эксперт .NET
10692 / 8854 / 2215
Регистрация: 17.09.2011
Сообщений: 15,222
Завершенные тесты: 1
14.08.2016, 13:19 13
Цитата Сообщение от ValeriiK Посмотреть сообщение
при 1 букве в строке это условие (str.Length > 1) завершает рекурсию и далее должно вывести эту букву.
Почему вы считаете, что оно дальше должно вывести эту букву?
У вас условие: если длина более одного символа, то сделать рекурсивный вызов.
Длина вашей строки — ровно один символ, значит блок if выполнен не будет, а будет выполнен блок else. Что в блоке else? Там один return — завершение метода. До вывода строки выполнение не доходит.

Добавлено через 2 минуты
Вот тот же метод, но с явно выделенными областями выполнения:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        public void DisplayReverse(string str)
        {
            if (str.Length > 0) ///При длине строки в 1-цу, 2-ой аргумент сабстринг будет равен 0
            {
                DisplayReverse(str.Substring(1, str.Length - 1)); 
            }
            else
            {
                return;
            }
            Console.Write(str[0]);///Как я думал (неправильно), первый вывод в рекурсии должен произойти при длине строки в 
                                  /// в один символ. Почему при условии if (str.Length > 1) не выводит последнею букву??? 
 
        }
0
EveKS
457 / 404 / 166
Регистрация: 19.04.2016
Сообщений: 1,604
Завершенные тесты: 7
14.08.2016, 13:22 14
ValeriiK, и это правильно копировали?
C#
1
Console.Write(str[str.Length - 1]);//моё
C#
1
Console.Write(str[0]);//не моё
Если так, то str.Substring(0, str.Length - 1), который должен отрезать последнюю букву -- этого не дулает =), а следовательно нужно написать разработчикам VS о том что в их програмке есть Ошибка.
Substring(0, str.Length - 1) Извлекает подстроку из данного экземпляра. Подстрока начинается с указанной позиции знака и имеет указанную длину. А в моем случае с [0] позиции, и имеет длинну str.Length - 1, что меньше на 1 букву чем в str т.к. str.Length > str.Length - 1 на 1.
А так как тут Console.Write(str[str.Length - 1]) я вывожу последнюю букву(индексация в C# с 0), то каждый раз последняя буква имеет индекс на 1 единицу меньше, т.к. строка короче на 1 из str.Length - 1;

Ушел писать разрабам об их ошибке со строками.

Добавлено через 2 минуты
Цитата Сообщение от kolorotur Посмотреть сообщение
return
ValeriiK, а вот если вы внимательно читали, в Шилдте про return написано в темах до.
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 13:28  [ТС] 15
kolorotur, вывод строки не входит в блок if, поэтому я и считаю, что если в слове осталась 1 буква, то при условии (str.Length > 1) сработает блок else, а далее вывод последней (единственной в строке) буквы.
А при условии (str.Length > 0) в DisplayReverse(str.Substring(1, str.Length - 1)) отправят (если я правильно понимаю Substring) пустую строку, сработает else, должен быть пустой вызов Console.Writeline(). Но этого не происходит - почему?
0
kolorotur
Эксперт .NET
10692 / 8854 / 2215
Регистрация: 17.09.2011
Сообщений: 15,222
Завершенные тесты: 1
14.08.2016, 13:34 16
Лучший ответ Сообщение было отмечено ValeriiK как решение

Решение

Цитата Сообщение от ValeriiK Посмотреть сообщение
поэтому я и считаю, что если в слове осталась 1 буква, то при условии (str.Length > 1) сработает блок else, а далее вывод последней (единственной в строке) буквы.
Вот в этом месте у вас ошибка.
После выполнения команды return всё, что стоит ниже, выполнено не будет.
Метод просто завершит выполнение.
0
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 13:44  [ТС] 17
kolorotur, я об этом догадывался, но меня смущало одно - тогда в этом случае как быть с Substring? Почему в этом методе не выдает ошибку при вызове str.Substring(1,0)? Я проверял, запустить в Main, то неизбежна ошибка. Почему такие двойные стандарты?
И еще я думал, что в методе void return действует только на if...
0
kolorotur
Эксперт .NET
10692 / 8854 / 2215
Регистрация: 17.09.2011
Сообщений: 15,222
Завершенные тесты: 1
14.08.2016, 13:53 18
Цитата Сообщение от ValeriiK Посмотреть сообщение
как быть с Substring?
А что с ним не так?

Цитата Сообщение от ValeriiK Посмотреть сообщение
Почему в этом методе не выдает ошибку при вызове str.Substring(1,0)?
По документации метода Substring:
A string that is equivalent to the substring of length length that begins at startIndex in this instance, or Empty if startIndex is equal to the length of this instance and length is zero.
Вольный перевод части после запятой: возвращает пустую строку, если начальный индекс равен длине строки, а длина (аргумент) равен нулю.
Как раз ваш случай: начальный индекс равен единице (строка длиной в один символ) и длина равна нулю (Length - 1 = 1 - 1 = 0).

Добавлено через 49 секунд
Цитата Сообщение от ValeriiK Посмотреть сообщение
И еще я думал, что в методе void return действует только на if
Вы, скорее всего, перепутали return и break.
1
ValeriiK
1 / 1 / 1
Регистрация: 05.01.2015
Сообщений: 85
14.08.2016, 15:06  [ТС] 19
kolorotur, спасибо! почему при вызове
C#
1
2
3
            string f = "F";
            string g = f.Substring(1, str.Length - 1);/// - длина равна нулю, начальный индекс эквивалентен длине строки..
            Console.WriteLine("String F is Substringed from 1 to 0(1-1) "+g);
почему выдает ошибку?

Добавлено через 3 минуты
EveKS, спасибо, для меня Вы написали более простой и следовательно более понятный для новичка пример, чем в книге.
0
kolorotur
Эксперт .NET
10692 / 8854 / 2215
Регистрация: 17.09.2011
Сообщений: 15,222
Завершенные тесты: 1
14.08.2016, 19:01 20
Цитата Сообщение от ValeriiK Посмотреть сообщение
почему при вызове выдает ошибку?
Потому что вы метод вызываете на строке f, а длину передаете от строки str. Которая, похоже, длиннее одного символа.
0
14.08.2016, 19:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.08.2016, 19:01

Рекурсия. Число N представить как сумму натуральных слагаемых
Помогите с программой. Реализуйте рекурсивный алгоритм, распечатывающий...

Что такое бесконечная рекурсия и как от неё избавляются?
Что такое бесконечная рекурсия и как от неё избавляются?

Цикл работает неправильно, в то время как POST работает
Всем привет! Я хотел написать под php скрипт с авторизацией, брут, на своем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru