Простой рекурсивный вопрос - PullRequest
1 голос
/ 03 августа 2010

Допустим, у нас есть простая рекурсия типа.

int x(int a){
   if(a<10)
     x(a+1);
    else
      !STOP!
    b++;
return b;
}

Globaly:

int b=0;

В основном мы могли бы иметь что-то вроде этого:

  int p=x(1);

Есть ли способ остановить рекурсию, чтобы p было равно 0, это означает, что "b ++" никогда не будет выполнен.

Буду признателен, если вы подскажете мне какое-нибудь выражение вместо! STOP!

Но я не хочу ничего подобного, я просто хочу остановить рекурсию, как перерыв; выполняет цикл while () ...:

int ok=0;
  int x(int a){
       if(a<10)
         x(a+1);
        else
          ok=1;
      if(ok==0)
        b++;
    return b;
    }

Если что-то неясно в этом вопросе, просто спросите.

Ответы [ 6 ]

7 голосов
/ 03 августа 2010

Почему бы вам не сделать это?

int x(int a){
   if(a<10) {
      x(a+1);
      b++;
   }
   return b;
}

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

Вы не можете "сломаться"рекурсия - возвращение раскручивается достаточно хорошо.В старом C вы можете использовать setjmp / longjmp (и все его опасности - другими словами, НЕ делать), а в C ++ вы можете использовать try / catch / throw, что также размотает стек.

1 голос
/ 03 августа 2010

Единственное в C ++, что раскручивает стек таким образом, является исключением. Также есть setjmp()/longjmp(), но они никогда не должны использоваться в программе на C ++. Любая другая конструкция может не более чем возвращаться из текущей функции.

1 голос
/ 03 августа 2010

Как насчет возвращения?

int x(int a){
   if(a<10)
     x(a+1);
    else
      return b;
    b++;
return b;
}

Я думаю, что это выглядит немного лучше

int x(int a){
   if(a<10)
     x(a+1);
    else
      return b;

    return ++b;
}

EDIT:

Я думаю, вы можете использовать механизм исключений, чтобы развернуть стек и добраться до точки первого вызова, но это безопасно после ввода main(). Ссылка b в x, с кодом:

int b = 0;
int p = x(1);

предполагает, что x используется для инициализации некоторой глобальной переменной и может выполняться до main(). Как насчет использования некоторой вспомогательной функции, которая переносит вызов x в блок try-catch и создает исключение вместо | STOP |?

1 голос
/ 03 августа 2010

Как насчет этого?

int x(int a){
   if(a>0 && a<10)
     x(a+1);
   b++;
   return b;
}
0 голосов
/ 03 августа 2010

Я не большой поклонник использования исключения для контроля.Я не ожидаю, что вы сэкономите много циклов, используя исключения вместо операторов if / return.Вам все равно придется проверить свои граничные условия, прежде чем выдавать исключение.

Однако вы можете немного упростить задачу, изменив тип возвращаемого значения функции.

0 голосов
/ 03 августа 2010

Если вы пытаетесь объявить b в main() и использовать b в x(), то с самого начала уже что-то не так. Вместо этого сделайте b локальной переменной, передав ее в качестве параметра x и вернув модифицированную версию b.

int x(int a, int b){
   if(a<10)
      return x(a+1,b+1);
    else
      return b;
}
...