2010-08-03 5 views
1

Disons que nous avons une récursion simple comme.Question de récursion simple

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

globaly:

int b=0; 

En principal, nous pourrions avoir quelque chose comme ceci:

int p=x(1); 

Est-il possible d'arrêter la récursion afin que le p sera de 0, ce moyen que "b ++" ne sera jamais exécuté.

Je vous serais reconnaissant si vous pouviez me dire une expression à mettre au lieu de la! STOP! Mais, je ne veux rien de pareil, je veux juste arrêter la récursion, comme casser; fait dans un moment() boucle ...:

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

S'il n'y a pas quelque chose de flou à propos de la question, il suffit de demander.

+0

Oh, et quand je veux arrêter la récursion Je veux dire aussi la suppression de la pile ... automaticaly – Cristy

+0

Cristy, vous pouvez modifier votre question plutôt que d'ajouter des commentaires. –

+0

Pourquoi voulez-vous faire cela? Il semble que vous utilisiez le mauvais outil pour le travail, mais il est difficile de le dire sans un exemple concret de ce que vous prévoyez faire. –

Répondre

7

Pourquoi ne pas le faire?

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

La chose est, cependant, vous modifiez une approche globale dans une routine récursive, ce qui est particulièrement threadsafe et assez bâclée. Vous renvoyez une valeur toujours ignorée sauf par l'appelant de niveau supérieur. Vous faites aussi quelque chose qui vaut mieux être fait en boucle (mais je suppose que votre cas réel est plus grand que celui-ci, ou vous êtes un étudiant).

Vous ne pouvez pas vraiment "casser" la récursion - retournant assez se déroule assez bien. En C oldey-timey vous pouvez utiliser setjmp/longjmp (et tous ses périls - en d'autres termes, NE PAS), et en C++, vous pouvez utiliser try/catch/throw, qui va également dérouler la pile.

+0

Merci pour les answear! Donc l'idée est que je ne peux pas "casser" une récursion ... Quoi qu'il en soit, l'idée de faire ceci était d'arrêter le programme de calculs inutiles ... Je veux dire, je pourrais avoir une récursion qui était nécessaire pour aller tout le chemin en avant, et puis, en revenant à arrêter à mi-chemin de la récursion, sans "récurer" à travers la moitié restante. Je ne peux pas expliquer trop bien, mais j'espère que vous obtenez ce que je suis en train de dire: D – Cristy

+1

Comme le dit plinth, vous pourriez jeter une exception dans ce cas. –

+0

Je n'ai jamais utilisé throw & catch et j'ai beaucoup programmé ces 2 dernières années. Je veux dire que je devrais vraiment lire à ce sujet. :) – Cristy

1

Que diriez-vous de pareil?

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

Ce code va simplement exécuter b ++; pour 1 fois si j'appelle la fonction comme x (1). Parce que 1 <0 && 1 <10 sera faux. Cela arrête simplement la fonction d'entrer dans la récursivité, cela n'empêche pas la récursivité de "revenir en arrière" une fois qu'il a commencé ... – Cristy

+0

@Jerry désolé, à ce sujet, corrigé ma faute de frappe. –

1

Que diriez-vous de revenir?

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

Je pense que cela ressemble un peu mieux

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

    return ++b; 
} 

EDIT:

Je pense que vous pouvez utiliser le mécanisme d'exception pour se détendre la pile et arriver au point de la première invocation, mais c'est sûr après avoir entré main(). Référençant b dans x, étant donné le code:

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

suggère que x est utilisé pour l'initialisation d'une variable globale et peut être exécuté avant main(). Que diriez-vous d'utiliser une fonction d'aide qui entoure l'invocation de x dans un bloc try-catch et qui lance une exception à la place de | STOP |?

+1

L'idée, je crois, est d'être capable d'annuler tout le calcul, de rejeter les résultats intermédiaires et d'annuler tout traitement ultérieur. 'return' arrête juste le calcul de continuer avec plus de récursion. –

+0

@David Thornley Je vois, thx :) –

+0

Si je vais utiliser le retour, il va juste arrêter l'appel en cours de la fonction pour continuer et reviendra et continuer la récursivité ... Je veux dire, quand je dis! STOP! Je veux vraiment dire arrêter: D. (totalement quitter la fonction sans appels futurs de la récursivité, effacer la pile ...) – Cristy

1

La seule chose en C++ qui va dérouler la pile comme ça est une exception. Il y a aussi setjmp()/longjmp(), mais ceux-ci ne devraient jamais être utilisés dans un programme C++. Toute autre construction peut tout au plus revenir de la fonction en cours.

0

Si vous essayez de déclarer b dans main(), et d'utiliser b dans x() alors il y a quelque chose de mal pour commencer. Au lieu de cela, rendez b dans une variable locale en le passant en paramètre à x et en renvoyant une version modifiée de b.

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

C'est juste un exemple rapide que j'ai créé. J'ai mis ce b ++; dans la fonction pour montrer qu'il y aurait du code après l'appel de récursion dans la fonction que je ne veux pas être exécuté ... :) – Cristy

+0

Vous pouvez également supprimer l'autre car il est redondant, une fois que le programme le retourne ne sera jamais exécuter le code ci-dessous. – ChickSentMeHighE

+0

@ChikSentMeHighE: ne pas nitpick :( –

0

Je ne suis pas un grand fan de l'utilisation d'une exception pour le contrôle. Je ne m'attends pas à ce que vous sauviez plusieurs cycles en utilisant des exceptions au lieu des instructions if/return. Vous allez devoir tester vos conditions aux limites avant de lancer une exception.

Vous pouvez cependant simplifier un peu le problème en modifiant le type de retour de la fonction.

bool x(int a){ 
    if(ok) //Exit early before next call up? 
    return true; 
    if(a<10){ 
    if(x(a+1)) //Have we been told to exit early? 
     return true; //Yes 
    b++; //Do some work 
    if(ok) //Exit early in the next call down? 
     return true; 
    } 
    return false; //Normal Exit 
} 
+0

C'est un peu en désordre, et ne toujours pas "arrêter" la récursivité: D ... Merci de toute façon aide :). – Cristy

+0

Pourriez-vous expliquer comment cela ne "stoppe" pas la récursivité? –