Programmation ardue fonction récursive en C
Fermé
bernard
-
11 févr. 2010 à 16:32
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 5 mars 2010 à 23:25
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 5 mars 2010 à 23:25
A voir également:
- Programmation ardue fonction récursive en C
- Fonction si et - Guide
- Application de programmation - Guide
- Fonction moyenne excel - Guide
- Fonction miroir - Guide
- Fonction somme excel - Guide
6 réponses
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
11 févr. 2010 à 16:52
11 févr. 2010 à 16:52
n vaut entre 0 et 4 ?
Je croi détecter une boucle infini.
si m!=0 et n!=0 et tableau[m][n]==0 alors tu appels la fonction "ackermann(m,n,tableau)" c'est à dire que tu n'as rien changé.
il faut : ackermann(m,ackermann(m,n-1,tableau),tableau) je pense.
Je mettrait tout en "long" aussi.
Par contre, ackermann(m,n-1,tableau) pourrait renvoyer un truc plus grand que 3 et posé un problème de taille de tableau non ?
Je croi détecter une boucle infini.
si m!=0 et n!=0 et tableau[m][n]==0 alors tu appels la fonction "ackermann(m,n,tableau)" c'est à dire que tu n'as rien changé.
il faut : ackermann(m,ackermann(m,n-1,tableau),tableau) je pense.
Je mettrait tout en "long" aussi.
Par contre, ackermann(m,n-1,tableau) pourrait renvoyer un truc plus grand que 3 et posé un problème de taille de tableau non ?
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
12 févr. 2010 à 08:25
12 févr. 2010 à 08:25
à peu près la même chose. Je suis déjà plus d'accord avec le 4 où tu l'as mis.
par contre le dernier else !!!
Si ton tableau est différent de 0 (si tu l'as rempli donc) alors tu calcul la valeur et tu la retournes !?
ce que je verrai :
e dois stocker chaque appel dans le tableau, donc tu es d'accord que pour stocker une valeur de A(m,n), je dois faire (je précise qu'à la base toutes les cases du tableau sont à 0):
if(tableau[m][n] == 0){
var=ackermann(m,n,tableau);
tableau[m][n]=var
jusqu'ici es tu d'accord avec ça?
absolument pas !
Je persiste sur ton var=, tu tombe sur une boucle infinie. Fait un test à la main pour t'en convaincre.
par contre le dernier else !!!
Si ton tableau est différent de 0 (si tu l'as rempli donc) alors tu calcul la valeur et tu la retournes !?
ce que je verrai :
long ackermann(long m, long n, long tableau[4][]) { long var; if(m==0){ return(n+1); }else if ((n==0){ return ackermann(m-1, 1, tableau); }else{ if(tableau[m][n] == 0){ var=ackermann(m,ackermann(m,n-1,tableau),tableau); tableau[m][n]=var; }else{ return tableau[m][n]; } }// accolade manquante }
e dois stocker chaque appel dans le tableau, donc tu es d'accord que pour stocker une valeur de A(m,n), je dois faire (je précise qu'à la base toutes les cases du tableau sont à 0):
if(tableau[m][n] == 0){
var=ackermann(m,n,tableau);
tableau[m][n]=var
jusqu'ici es tu d'accord avec ça?
absolument pas !
Je persiste sur ton var=, tu tombe sur une boucle infinie. Fait un test à la main pour t'en convaincre.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
12 févr. 2010 à 15:39
12 févr. 2010 à 15:39
oui, mais les retours sont dans des if.
met un return -1 à la fin. En plus ça permet de traiter les erreurs inattendus.
met un return -1 à la fin. En plus ça permet de traiter les erreurs inattendus.
la fonction compile bien mais j'ai une erreur de segmentation. Je crée un tableau de 5 colonnes et 65534 lignes et je l'initialise à 0 partout. Voici mon code complet en C:
#include <stdio.h>
long ackermann(long m, long n, long tableau[][65534]){
long var;
if(m==0){
return(n+1);
}else if ((n==0){
return ackermann(m-1, 1, tableau);
}else{
if(tableau[m][n] == 0){
var=ackermann(m,ackermann(m,n-1,tableau),tableau);
tableau[m][n]=var;
}else{
return tableau[m][n];
}
}
return -1;
}
int main(){
long tableau[5][65534];
long res;
long i,j;
for(i=1;i<=65534;i++){
for(j=1;j<=5;j++){
tableau[j][i]=0;
}
}
res=ackermann(2,3,TABLEAU);
printf("%ld\n", res);
return 0;
}
J'ai surement dû mélanger les cases qu'en dis tu?
#include <stdio.h>
long ackermann(long m, long n, long tableau[][65534]){
long var;
if(m==0){
return(n+1);
}else if ((n==0){
return ackermann(m-1, 1, tableau);
}else{
if(tableau[m][n] == 0){
var=ackermann(m,ackermann(m,n-1,tableau),tableau);
tableau[m][n]=var;
}else{
return tableau[m][n];
}
}
return -1;
}
int main(){
long tableau[5][65534];
long res;
long i,j;
for(i=1;i<=65534;i++){
for(j=1;j<=5;j++){
tableau[j][i]=0;
}
}
res=ackermann(2,3,TABLEAU);
printf("%ld\n", res);
return 0;
}
J'ai surement dû mélanger les cases qu'en dis tu?
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
12 févr. 2010 à 16:38
12 févr. 2010 à 16:38
Non, pas de mélange de case, mais en C les tableaux commencent à "0" !
donc :
for(i=0;i<65534;i++){
for(j=0;j<5;j++){
tableau[j][i]=0;
}
}
pour les tableaux, comme tu connais la taille autant la donner à chaque fois.
donc :
for(i=0;i<65534;i++){
for(j=0;j<5;j++){
tableau[j][i]=0;
}
}
pour les tableaux, comme tu connais la taille autant la donner à chaque fois.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
15 févr. 2010 à 08:04
15 févr. 2010 à 08:04
2 solutions : soit tu débug en mettant des print pour connaitre les valeurs soit tu fais une fonction prorpre.
Comme tu utilises un tableau, il faut tester voir si tu ne dépasses pas.
const int mMAX=5,nMAX=65534;
long ackermann(long m, long n, long tableau[mMAX][nMAX]){
if(m>=mMAX || n>=nMAX) //traitement particulier de l'erreur.
peut être même ajouter (on ne sais jamais)
if(m<0 || n<0) // etc.
Comme tu utilises un tableau, il faut tester voir si tu ne dépasses pas.
const int mMAX=5,nMAX=65534;
long ackermann(long m, long n, long tableau[mMAX][nMAX]){
if(m>=mMAX || n>=nMAX) //traitement particulier de l'erreur.
peut être même ajouter (on ne sais jamais)
if(m<0 || n<0) // etc.
#include<stdio.h>
#include<conio.h>
main()
{int n,m,y;
int Ack(int,int);
printf("entrez m:\n");
scanf("%d",&m);
printf("entrez n:\n");
scanf("%d",&n);
y=Ack(m,n);
printf("Ack(%d,%d)=%d\n",m,n,y);
getch();
}
int Ack(int m, int n)
{
if (m == 0)
return(n+1);
else{
if (n == 0)
return(Ack(m-1, 1));
else
return( Ack(m-1, Ack(m, n-1)));
}
}
#include<conio.h>
main()
{int n,m,y;
int Ack(int,int);
printf("entrez m:\n");
scanf("%d",&m);
printf("entrez n:\n");
scanf("%d",&n);
y=Ack(m,n);
printf("Ack(%d,%d)=%d\n",m,n,y);
getch();
}
int Ack(int m, int n)
{
if (m == 0)
return(n+1);
else{
if (n == 0)
return(Ack(m-1, 1));
else
return( Ack(m-1, Ack(m, n-1)));
}
}
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
5 mars 2010 à 23:25
5 mars 2010 à 23:25
Bonjour,
Tu n'as pas besoin de parcourir ton tableau pour le remplir à 0. Ca se fait facilement lors de la déclaration. De plus, l'utilisation du tableau est mal implémenté et tu as fait une erreur dans la définition de la fonction d'Ackermann.
var=ackermann(m,ackermann(m,n-1,tableau),tableau);
Il s'agit de m-1 en premier argument. Ce qui change tout...
Niveau algorithmique, j'aurais plutôt vu un truc du genre :
Ensuite, faudrait voir pour mieux gérer la taille du tableau, quitte à faire de l'allocation dynamique.
Cdlt,
Tu n'as pas besoin de parcourir ton tableau pour le remplir à 0. Ca se fait facilement lors de la déclaration. De plus, l'utilisation du tableau est mal implémenté et tu as fait une erreur dans la définition de la fonction d'Ackermann.
var=ackermann(m,ackermann(m,n-1,tableau),tableau);
Il s'agit de m-1 en premier argument. Ce qui change tout...
Niveau algorithmique, j'aurais plutôt vu un truc du genre :
#include <stdio.h> long ackermann(long m, long n, long tableau[][65534]) { if(m==0 && tableau[n][n]==0) tableau[0][n]=n+1; else if(n==0 && tableau[m][n]==0) tableau[m][0]=ackermann(m-1,1,tableau); else if(tableau[m][n]==0) tableau[m][n]=ackermann(m-1,ackermann(m,n-1,tableau),tableau); return tableau[m][n]; } int main(void) { long tableau[5][65534]={{0}}; printf("%ld\n", ackermann(2,3,tableau)); return 0; }
Ensuite, faudrait voir pour mieux gérer la taille du tableau, quitte à faire de l'allocation dynamique.
Cdlt,
11 févr. 2010 à 17:23
Je dois stocker chaque appel dans le tableau, donc tu es d'accord que pour stocker une valeur de A(m,n), je dois faire (je précise qu'à la base toutes les cases du tableau sont à 0):
if(tableau[m][n] == 0){
var=ackermann(m,n,tableau);
tableau[m][n]=var
jusqu'ici es tu d'accord avec ça?
11 févr. 2010 à 17:48
long ackermann(int m, int n, long tableau[4][]){
long var;
if(m==0){
return(n+1);
}else if ((n==0){
return ackermann(m-1, 1, tableau);
}else{
if(tableau[m][n] == 0){
var=ackermann(m,n,tableau);
tableau[m][n]=var;
return tableau[m][n];
}else{
return ackermann(m-1,ackermann(m,n-1,tableau),tableau);
}
}
}