La récursivité de la fonction pour trouver la puissance d'un nombre
Je suis en train d'écrire une récursivité de la fonction pour trouver la puissance d'un nombre et il semble être de la compilation, mais ne pas afficher quoi que ce soit.
#include <iostream>
using namespace std;
int stepem(int n, int k);
int main()
{
int x, y;
cin >> x >> y;
cout << stepem(x, y) << endl;
return 0;
}
int stepem(int n, int k)
{
if (n == 0)
return 1;
else if (n == 1)
return 1;
else
return n * stepem(n, k-1);
}
J'ai essayé de débogage, et il dit que le problème est sur cette ligne :
return n * stepem(n, k-1);
k semble un peu bizarre, mais je ne peux pas comprendre pourquoi?
- Eh bien la vérité est que votre
n
n'est jamais en train de changer. C'est probablement le fait d'une récursion infinie jusqu'à ce que vos piles se remplir. - N'est-ce pas une boucle infinie?
- Eh bien, il ne faut pas changer, pourquoi devrait-il? Je veux multiplier le nombre
n
pourk
fois. - Je pense que vous voulez vérifier
k
et pasn
, je me trompe? - non, parce que la récursivité n'est pas la queue récursive
Vous devez vous connecter pour publier un commentaire.
Vous devriez vérifier l'exposant k, pas le nombre lui-même qui ne change jamais.
Votre k est d'obtenir des valeurs étranges parce que vous allez garder le calcul jusqu'à ce que vous manquez de mémoire, fondamentalement, vous permettra de créer de nombreux pile d'images avec k allant à "l'infini" (hypothétiquement).
Cela dit, il est théoriquement possible que le compilateur de vous donner un avertissement qu'il n'aura jamais de fin - dans ce scénario particulier. Toutefois, il est naturellement impossible de résoudre cette question de manière générale (rechercher le problème de l'Arrêt).
k
plus grand queMAX_INT
pourrait pas créer un stackoverflow avec ma version, il devrait donner des résultats inattendus à certains points, si les chiffres sont trop élevés pour les services de renseignements.Votre algorithme est faux:
Si vous l'appelez, avec
stepem(2, 3)
(par exemple), vous aurez 2 * 2 * 1 au lieu de 2 * 2 * 2 * 1. Vous n'avez pas besoin de else-if condition:return n;
quandk == 1
dans votre révision du code d'origine?n * stepem(n, 0)
équivaut àn * 1
. La seule porte de sortie de la condition que vous avez besoin est dek == 0
.k == 1
vérifier).return
est changé àreturn n;
— même si il serait également fonctionner correctement (mais un peu plus cher) si leelse if (k == 1) return n;
condition ont été supprimés, de même que dans la deuxième version du code. La différence est moins un appel de fonction vs un plus test — pas énorme.N'ai pas tester, mais je suppose que cela devrait vous donner ce que vous voulez et c'est la queue récursive.
La grande différence entre ce morceau de code et l'autre exemple est que ma version pourrait obtenir optimisé pour queue d'appels récursifs. Cela signifie que lorsque vous appelez
stepemi
de manière récursive, il n'a pas à garder quelque chose en mémoire. Comme vous pouvez le voir, il pourrait remplacer la variable dans l'actuel cadre de la pile sans avoir à en créer un nouveau. Aucune variable à rester dans la mémoire pour calculer la suivante récursivité.Si vous pouvez avoir optimisé la queue d'appels récursifs, cela signifie également que la fonction sera utilisée d'un montant fixe de la mémoire. Il n'aura jamais besoin de plus de 3 ints.
D'autre part, le code que vous avez écrit à la première crée un arbre de la structure de pile en attente de retour. Chaque récursion s'ajoutera jusqu'à la prochaine.
int
au lieu de 3byte
?Bien, juste pour poster une réponse en fonction de mon commentaire (il semble que j'ai manqué d'ajouter un commentaire et non une réponse :-D). Je pense que, surtout, vous avez deux erreurs: vous êtes à la vérification de
n
au lieu dek
et vous êtes de retour1
quand la puissance est de 1, au lieu de retournern
. Je pense questepem
fonction devrait ressembler à:Edit: mis à Jour pour supporter les exposants négatifs par @ZacHowland suggestion
<=0
vérifier. Sik
est négatif, la valeur de retour (mathématiquement) serait une fraction, pas 1. La plus sûre solution est de prévenir les nombres négatifs pour l'exposant, tout à fait (à moins que le désir est de manipuler des nombres à virgule flottante).votre Programme est mauvais et qu'il Ne prend pas en charge négative de la valeur donnée par l'utilisateur,
vérifier celui-ci
désolé, j'ai changé les noms de variables
mais j'espère que vous comprendrez;