Recurrence et Variable identique / Règles d'écritures

Recurrence et Variable identique / Règles d'écritures - C++ - Programmation

Marsh Posté le 17-11-2008 à 11:01:15    

Bonjour,
 
Je dois programmer une méthode d'une classe qui utilise la récurrence mais dont l'appel utilise également une variable qui ne sera pas modifiée d'appel en appel. Je voudrais savoir quelle est la règle d'écriture la plus propre à adopter.
 
Plus simplement, par exemple, si je veux calculer la fonction qui a " n " associe " n ! + m ", dans une classe MonMath, je dois écrire :

Code :
  1. MonMath::mafactorielle(int n,int m)
  2. {
  3. if (n==0)
  4.       return (1+ m);
  5. else
  6.       return (mafactorielle(n-1,m);
  7. }


Ce qui me gène, dans mon cas qui est plus complexe que celui présenté ici, c'est que la variable " m " peut être grande en taille mémoire et que son utilisation systématique peut être lourde à gérer. Je voudrais donc savoir comment se ramener à une écriture plus propre en terme de récurrence, du type :

Code :
  1. MonMath::mafactorielle(int n)
  2. {
  3. if (n==0)
  4.       return (1 + m);
  5. else
  6.       return (mafactorielle(n-1);
  7. }


Est-ce que, dans cette situation, il vaut mieux définr la variable m comme une variable globale ou comme une variable statique. Dans les deux, cas, elle restera visible dans la méthode, avec une valeur qui lui aura été affectée avant le premier appel à mafactorielle. Ce qui me gêne dans la première écriture, c'est le transport, dans l'ensemble des appels sucessifs d'une variable m qui ne se révèle utilse que à la fin, lors de l'ultime appel.
 
Est-ce que vous pourriez ainsi me conseiller une règle d'écriture propre ?
 
Merci d'avance de votre aide,
 
NathanGe
 
 

Reply

Marsh Posté le 17-11-2008 à 11:01:15   

Reply

Marsh Posté le 17-11-2008 à 12:11:49    

Si ton objet à empiler est gros:
- si c'est de l'allocation sur la pile, si c'est de la récursivité terminale ça ira tout seul
- si c'est de l'allocation dynamique ça va tout de suite moins bien marcher puisqu'en fin d'appel récursif, il faudra revenir dans le contexte appelant pour détruire les resources (explicitement ou un implicitement). Donc dans ce cas là, soit tu passes un pointeur vers le nouvel objet dans l'appel récursif, et c'est l'appelé qui le détruit lui même, soit tu passes en itératif. Si ton objet est modifié à chaque appel (-1 ou +1 par exemple), tu peux aussi te contenter de le passer par & (pas const), ça revient au cas du pointeur - la désallocation. Gare au effet de bords

Reply

Marsh Posté le 17-11-2008 à 12:15:48    

Genre

Code :
  1. #include <vector>
  2. void recurse_helper(std::vector<int>& v, unsigned& n)
  3. {
  4.   if (n != 0) {
  5.     v.push_back(n);
  6.     n--;
  7.     recurse_helper(v, n);
  8.   }
  9. }
  10. void recurse(std::vector<int> v, unsigned n)
  11. {
  12.   recurse_helper(v, n);
  13. }


 
Tu travailles avec une copie de ton paramètre initial (que ce soit un vecteur ou un entier). Mais ça tourne vite à la récursivité battarde. A toi de voir.

Reply

Marsh Posté le 17-11-2008 à 14:35:00    

recursivitéG [:sadnoir]

 

la récursivité c'ets bien mais bon, faut rester pragmatique sur la faisabilité de la chose sur de vrais machine.


Message édité par Joel F le 17-11-2008 à 14:35:39
Reply

Marsh Posté le 17-11-2008 à 15:07:05    

en fait il te faut faire la même technique qu'en fonctionnel pour rendre une fonction terminale: un paramètre modifié et modifiable que tu transportes entre appel.

Reply

Marsh Posté le 17-11-2008 à 15:29:59    

En fonctionnel le pb se pose différemment, tu passe tout en valeur anyway

Reply

Marsh Posté le 17-11-2008 à 16:13:29    

Bah tu passes ton pointeur par valeur et pas par référence et voilà :)

Reply

Marsh Posté le 17-11-2008 à 16:16:23    

tu conviendras que la notion de pointeur en langage fonctionnel reste un truc à spécifier proprement ;)

Reply

Marsh Posté le 17-11-2008 à 17:54:00    

Il s'agit, dans mon cas plus complexes que celui décrit, de paramètres permettant de communiquer avec Access pour mes bases de données.
Ces paramètres (char* avec adresse de fichier ....) sont actuellement transmis à chaque appel de la méthode par récurrence. Cependant, il ne sont utilisés que lors du dernier appel, lorsque n est nul.  
 
Dans une première version du code, j'avais mis les objets en static dans la méthode, en considérant que cela était plus propre pour gérer la récurrence, car cela évitait de rappeler une méthode qui ne l'utilisait que dans un cas précis, où n était nul.
 
D'après la réponse de Taz, je vais sans doute mettre ces objets dans les arguments de la méthode finalement.
 

Reply

Marsh Posté le 17-11-2008 à 20:08:50    

euh ça coute rien ton problèmes, c'est juste une poignée de pointeurs ! ça va te manger quelques octets sur la pile si t'es pas récursif terminal, sinon c'est impact 0.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed