Как присвоить уникальный идентификатор каждому рекурсивному вызову метода?

Пытаюсь познать рекурсию во всей её глубине на учебных примерах. Для облегчения этой задачи мне было бы очень полезно точно знать какой именно рекурсивный вызов работает в данный момент (например, посредством вывода этой информации на консоль). Простой счётчик тут не подходит, потому что нужно не просто посчитать, сколько всего было рекурсивных вызовов, а знать какой по счёту вызов относительно самого первого выполняется в данный момент.

Если бы можно было присвоить каждому вызову уникальный идентификатор (номер, например), который бы можно было вывести на консоль при рекурсивном вызове метода, а также при возврате в него после того, как последующие рекурсивные вызовы закончат работу, это бы мне очень помогло составить в голове полную картину.

Подскажите, пожалуйста, возможно ли это?

P.S. Речь идет не о хвостовой рекусии - это просто и вопросов не вызывает. Случай значительно сложнее - рекурсивные вызовы помещены внутрь цикла, и аргументы, передаваемые в рекусивно вызываемый метод зависят от итерации этого цикла.


Ответы (1 шт):

Автор решения: MBo

Если я правильно понял, что вам требуется:
При входе в функцию увеличиваете глобальный счётчик, и копируете его значение в локальную переменную, которая сохранит это значение до возврата из нижележащих рекурсивных вызовов.

using System;
class HelloWorld {
  static int Cnt = 0;    
  static int Req(int n) {
     int MyId = ++Cnt; 
     for (int i = 0; i < MyId ; i++) Console.Write("  ");
     Console.WriteLine("Id " + MyId);
     int res = n;
     for (int i = 0; i < n ; i++) {
         res += Req(i);
     }
     for (int i = 0; i < MyId ; i++) Console.Write("  ");
     Console.WriteLine("Id "+ MyId + " Exit");
     return res;
  }    
  static void Main() {
    Console.WriteLine(Req(4));
  }
}

...

 Id 1
    Id 2
    Id 2 Exit
      Id 3
        Id 4
        Id 4 Exit
      Id 3 Exit
          Id 5
            Id 6
            Id 6 Exit
              Id 7
                Id 8
                Id 8 Exit
              Id 7 Exit
          Id 5 Exit
                  Id 9
                    Id 10
                    Id 10 Exit
                      Id 11
                        Id 12
                        Id 12 Exit
                      Id 11 Exit
                          Id 13
                            Id 14
                            Id 14 Exit
                              Id 15
                                Id 16
                                Id 16 Exit
                              Id 15 Exit
                          Id 13 Exit
                  Id 9 Exit
  Id 1 Exit
15

Если вам нужен только текущий уровень рекурсии:

using System;
class HelloWorld {
  static int Req(int n, int level = 0) {
     for (int i = 0; i < level ; i++) Console.Write("  ");
     Console.WriteLine("level " + level);
     int res = n;
     for (int i = 0; i < n ; i++) {
         res += Req(i, level + 1);
     }
     for (int i = 0; i < level ; i++) Console.Write("  ");
     Console.WriteLine("level "+ level + " Exit");
     return res;
  }    
  static void Main() {
    Console.WriteLine(Req(4));
  }
}
→ Ссылка