La suite de Fibonacci en C

La suite de Fibonacci en C - C - Programmation

Marsh Posté le 25-10-2006 à 16:52:37    

Bonjour,
 
Je bloque sur un exos de TP, je vais vous l'exposer:

Citation :


Ecrire un programme qui affiche le nième terme de la suite de Fibonacci, définie par la relation de récurence:
 
U(0) = U(1) = 1
Pout tout n >= 2 , Un = U(n -1) + U(n -2)


 
Bon alors évidement, tout le monde ce doute que j'ai le début :
 

Code :
  1. /* Ecrire un programme qui affiche le nième terme de la suite de Fibonacci */
  2. #include<math.h>
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. int main(void)
  6. {
  7.   int a,b,c,n;
  8.   printf("Entrez le n terme de la suite:" );


 
Et la le noir totale, plus rien!
 
DOnc si on pouvais me filer un coup de pouce! Merci !

Reply

Marsh Posté le 25-10-2006 à 16:52:37   

Reply

Marsh Posté le 25-10-2006 à 16:54:47    

Bah t'écris une boucle qui pour chaque itération utilise les résultats des itérations précédentes.
 
Au passage, ca doit craquer l'exemple chez google.


Message édité par _darkalt3_ le 25-10-2006 à 16:55:03

---------------
Töp of the plöp
Reply

Marsh Posté le 25-10-2006 à 17:01:17    

je sait que ça doit craquer mais j'essaye de trouver seul, donc avec des pistes uniquement.

Reply

Marsh Posté le 25-10-2006 à 17:09:34    

Euuuh la première erreur, c'est que la suite de Fibonacci renvoie 0 si on lui donne 0, pas 1.
 
Sinon, ben commences par créer une fonction récursive qui réplique exactement la définition de l'algo.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 25-10-2006 à 18:38:08    

J'en refais un avec les switch/case ? [:dawa]

Reply

Marsh Posté le 25-10-2006 à 18:44:21    

0x90 a écrit :

J'en refais un avec les switch/case ? [:dawa]


+1 [:dawa]


---------------
Töp of the plöp
Reply

Marsh Posté le 25-10-2006 à 21:21:22    

rafalfa2000 a écrit :

je sait que ça doit craquer mais j'essaye de trouver seul, donc avec des pistes uniquement.


 
Si tu sèches déjà sur cet algo de base, je crains pour la suite. D'ailleurs c'est plus un topic "algo" que "C"...
Tu définis un tableau "int u[3]={1, 1, 0}"
Tu fais une itération de 1 à n
A chaque boucle, tu recalcules "u[2]" en fonction de "u[0]" et "u[1]" puis tu copies "u[1]" dans "u[0]" puis "u[2]" dans "u[1]" comme ça les valeurs sont prêtes pour recalculer "u[2]" au tour de boucle suivant.
En fin de boucle, tu affiches "u[2]"...
 

masklinn a écrit :

Sinon, ben commences par créer une fonction récursive qui réplique exactement la définition de l'algo.


Utiliser la récursivité sur Fibonacci, c'est aller droit dans le mur. Essaye de calculer "fib(26)" en récursif...

Message cité 1 fois
Message édité par Sve@r le 25-10-2006 à 21:30:02

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 25-10-2006 à 22:30:46    

stack overflow spotted  :sarcastic:

Reply

Marsh Posté le 25-10-2006 à 22:33:16    

Sve@r a écrit :

Utiliser la récursivité sur Fibonacci, c'est aller droit dans le mur.


J'ai parlé de commencer comme ça, sans vouloir être méchant au stade où il en est c'est largement suffisant d'utiliser la définition canonique [:pingouino]

Sve@r a écrit :

Essaye de calculer "fib(26)" en récursif...


Code :
  1. fibbase 0 = 0
  2. fibbase 1 = 1
  3. fibbase n = fibbase (n-1) + fibbase (n-2)


Math> fibbase 26
121393
Math> fibbase 30
832040


 
C'est un peu trop facile en fait, alors je vais plutôt te donner une implé récursive qui sort du fibo(5000) ok?

Code :
  1. Math> fibo 5000
  2. 3878968454388325633701916308325905312082127714646245106160597214895550139044037097010822916462210669479293452858882973813483102008954982940361430156911478938364216563944106910214505634133706558656238254656700712525929903854933813928836378347518908762970712033337052923107693008518093849801803847813996748881765554653788291644268912980384613778969021502293082475666346224923071883324803280375039130352903304505842701147635242270210934637699104006714174883298422891491273104054328753298044273676822977244987749874555691907703880637046832794811358973739993110106219308149018570815397854379195305617510761053075688783766033667355445258844886241619210553457493675897849027988234351023599844663934853256411952221859563060475364645470760330902420806382584929156452876291575759142343809142302917491088984155209854432486594079793571316841692868039545309545388698114665082066862897420639323438488465240988742395873801976993820317174208932265468879364002630797780058759129671389634214252579116872755600360311370547754724604639987588046985178408674382863125


Implé:

Code :
  1. module Math where
  2. fiboIter 0 a _ = a
  3. fiboIter x a b = fiboIter (x - 1) b (a + b)
  4. fibo x = fiboIter x 0 1


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 25-10-2006 à 22:55:55    

karlkox a écrit :

stack overflow spotted  :sarcastic:


Pipeau ahead, captain.
 
$ ./fib 48
fib 48 -> 4807526976
 
En C, récursif et super lent.


Message édité par tbp le 25-10-2006 à 22:56:35
Reply

Marsh Posté le 25-10-2006 à 22:55:55   

Reply

Marsh Posté le 25-10-2006 à 23:43:32    

Je n'ai pas parlé de cet exemple en particulier, un stack overflow n'arrive pas pour une boucle si petite et cela dépend aussi du langage utilisé et de la ram libre disponible.

Reply

Marsh Posté le 26-10-2006 à 00:56:38    

Primo, ce n'est pas une boucle puisque c'est récursif. Secundo, qu'essayes tu donc de dire? Je rappelle que nous sommes dans la section 'C' du forum et qu'il y a fort peu de chance qu'un tel overflow arrive, même dans une implementation particulierement déficiente, avant que d'exploser la limite généralement constatée des 32bits par int; cf le code du post initial.

Code :
  1. int a,b,c,n;
  2. printf("Entrez le n terme de la suite:" );


Reply

Marsh Posté le 26-10-2006 à 17:06:05    

masklinn a écrit :

Code :
  1. fibbase 0 = 0
  2. fibbase 1 = 1
  3. fibbase n = fibbase (n-1) + fibbase (n-2)


Math> fibbase 26
121393
Math> fibbase 30
832040


 
C'est un peu trop facile en fait, alors je vais plutôt te donner une implé récursive qui sort du fibo(5000) ok?

Code :
  1. Math> fibo 5000
  2. 3878968454388325633701916308325905312082127714646245106160597214895550139044037097010822916462210669479293452858882973813483102008954982940361430156911478938364216563944106910214505634133706558656238254656700712525929903854933813928836378347518908762970712033337052923107693008518093849801803847813996748881765554653788291644268912980384613778969021502293082475666346224923071883324803280375039130352903304505842701147635242270210934637699104006714174883298422891491273104054328753298044273676822977244987749874555691907703880637046832794811358973739993110106219308149018570815397854379195305617510761053075688783766033667355445258844886241619210553457493675897849027988234351023599844663934853256411952221859563060475364645470760330902420806382584929156452876291575759142343809142302917491088984155209854432486594079793571316841692868039545309545388698114665082066862897420639323438488465240988742395873801976993820317174208932265468879364002630797780058759129671389634214252579116872755600360311370547754724604639987588046985178408674382863125


Implé:

Code :
  1. module Math where
  2. fiboIter 0 a _ = a
  3. fiboIter x a b = fiboIter (x - 1) b (a + b)
  4. fibo x = fiboIter x 0 1



 
Arrête de te la raconter. Evidemment si tu utilises un langage que je ne connais pas mais qui semble adapté maths, tu arriveras à calculer fib(5000) mais tu sais parfaitement qu'on est en C. Et une fonction récursive C pour calculer Fibonacci arrivera péniblement à fib(26) et mettra 2 fois plus de temps pour calculer fib(28) car il lui faudra calculer 2 fois fib(26). Et encore 2 fois plus de temps pour fib(30) etc. Ou alors on crée une fonction récursive intelligente qui détecte les valeurs déjà calculées pour ne pas les recalculer à chaque fois. Mais là, on sort du TP de base...

masklinn a écrit :

J'ai parlé de commencer comme ça, sans vouloir être méchant au stade où il en est c'est largement suffisant d'utiliser la définition canonique [:pingouino]


Chacun voit midi à sa porte. Moi je conseille de toujours tenter d'éviter la récursivité autant que possible car elle peut paraître alléchante mais on n'imagine pas le boulot de l'ordi par derrière... Et là, c'est franchement facile de ne pas faire du récursif...

Message cité 1 fois
Message édité par Sve@r le 26-10-2006 à 17:09:56

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 26-10-2006 à 17:19:49    

Sve@r a écrit :

Arrête de te la raconter.


WTF [:petrus dei]
 
J'ai juste prouvé que tu avais tord, rien de plus [:spamafote]  

Sve@r a écrit :

Evidemment si tu utilises un langage que je ne connais pas mais qui semble adapté maths


Ce n'est pas le cas, on peut faire la même chose en C, mais j'avais (et j'ai toujours) autre chose à faire que l'implémenter en C.
 
Le langage est Haskell, sa notation est très proches des mathématiques mais il n'a pas une implémentation spécialement dédiée aux maths (en dehors du fait qu'il est fonctionnel), contrairement à, disons, un Matlab

Sve@r a écrit :

Et une fonction récursive C pour calculer Fibonacci arrivera péniblement à fib(26) et mettra 2 fois plus de temps pour calculer fib(28) car il lui faudra calculer 2 fois fib(26). Et encore 2 fois plus de temps pour fib(30) etc.


C'est très exactement ce que fait la première implémentation [:marc]
 
C'est d'ailleurs la raison pour laquelle tu n'as pas vu de fib(5000) avec la première version [:marc]

Sve@r a écrit :

Ou alors on crée une fonction récursive intelligente qui détecte les valeurs déjà calculées pour ne pas les recalculer à chaque fois. Mais là, on sort du TP de base...


On memoize quoi.

Sve@r a écrit :

Chacun voit midi à sa porte. Moi je conseille de toujours tenter d'éviter la récursivité autant que possible car elle peut paraître alléchante mais on n'imagine pas le boulot de l'ordi par derrière... Et là, c'est franchement facile de ne pas faire du récursif...


Je sais pas si t'as remarqué, mais là le monsieur a déjà des problèmes avec l'IO, donc les optimisations du genre "implémente la fib en itératif plutôt qu'en récursif" j'pense que ça peut être vu après si tu veux, qu'il commence par l'implé canonique et par la suite il pourra en utiliser d'autres.


Message édité par masklinn le 26-10-2006 à 17:20:32

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 26-10-2006 à 21:07:44    

alors c'est bien beau tout ça mais moi en cour, j'en suis au boucle et au base de focntion.
 
D'ailleur, je doit faire cette exos a base de for(instruction;conditions;instruction);
 

Reply

Marsh Posté le 26-10-2006 à 22:46:53    

Ben c'est la méthode de Sve@r alors.

Reply

Marsh Posté le 27-10-2006 à 15:01:26    

Trap D a écrit :

Ben c'est la méthode de Sve@r alors.


Ce n'est pas la "mienne", c'est celle de la "logique". Juste une petite erreur dans la méthode en question: la boucle doit démarrer à 2 et non à 0...
 

rafalfa2000 a écrit :

alors c'est bien beau tout ça mais moi en cour, j'en suis au boucle et au base de focntion.
 
D'ailleur, je doit faire cette exos a base de for(instruction;conditions;instruction);


 
La méthode que j'ai expliquée hier. Si t'as pas appris les tableaux, alors la même sans ces derniers...
Tu définis 3 unsigned int a, b et c (unsigned long c'est même encore mieux).
Tu initialises "a" et "b" à 1 car ce sont les 2 premiers termes de la suite
Tu fais une itération de 2 à n (départ à 2 car les valeurs U0 et U1 sont déjà présentes dans "a" et "b" )
A chaque boucle, tu recalcules "c" en fonction de "a" et "b" puis tu copies "b" dans "a" puis "c" dans "b" comme ça les valeurs sont prêtes pour recalculer "c" au tour de boucle suivant.  
En fin de boucle, tu affiches "c"...


Message édité par Sve@r le 27-10-2006 à 15:04:26

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

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