Besoin d'aide en COMBINAISON

Besoin d'aide en COMBINAISON - C - Programmation

Marsh Posté le 04-03-2013 à 07:12:11    

Bonjour,
 
j'ai réalise un algorithme pour calculer la combinaison mais ca fonctionne pas. je crois qu'il ya un problème ds mon raisonnement. j'espère que vous pourrez m'aider thx d'avance. bon ya une parti qui est ds ma page "main" et l'autre est en "FONCTION"
 
----MAIN---
{
int nbr1,nbr2;
do
{ printf("P doit etre inferieur ou egal a N\n" );
printf("----Entrez la valeur de P\n" );
scanf("%4d",&nbr1);
printf("----Entrez la valeur de N\n" );
scanf("%4d",&nbr2);
}
while((nbr1<0)&&(nbr2<0));
if(nbr1>nbr2)
{
printf("---------------------------------------------------------------------\n" );
printf("RAPPEL:P doit etre inferieur ou egal a N\n" );
}
else
{
printf("La combinaison de %d dans %d est : %d\n", nbr1,nbr2,combinaison(nbr2,nbr1));
 
}
 
printf("\n" );
printf("\n" );
printf("---------------------------------------------------------------------" );
printf("\n" );
printf("\n" );
 
}
 
 
 
----FONCTION----
 
 
long combinaison(int n,int p)
{
long factn,factp,factdif,comb;
int dif,i;
factn=factp=factdif=1;//initialisation des variable factoriel a 1
dif=n-p;//ceci pour trouve la valeur de (n-p)!
if(n>0)// de maniere a ce que si la valeur est 0 on peut tjr appliquer la regle 0!
{//calcul de la factioriel de n
for(i=1;i<=n;i++)
{
factn=factn*i;
}
}
if(p>0)
{//calcul de la factioriel de p
for(i=1;i<=p;i++)
{
factp=factp*i;
}
}
if(dif>0)
{//calcul de la factioriel de la difference n et p
for(i=1;i<=dif;i++)
{
factdif=factdif*i;
}
}
comb=factn/(factp*factdif);
return comb;
}


---------------
kaima1
Reply

Marsh Posté le 04-03-2013 à 07:12:11   

Reply

Marsh Posté le 04-03-2013 à 07:57:22    

Hello kaima1,
 
Ton code fonctionne. J'ai essayé avec les valeurs P = 3 et N = 5 et ça me renvoie bien 10 qui est la valeur de C(5,3). Qu'est-ce qui te fait dire que ça ne fonctionne pas ?
Il y aurait des choses discutables dans ton code :
- définir une fonction pour calculer fact (en plus ça te permettrait d'écrire juste : return(fact(N)/(fact(P) * fact(N-P))) pour ta fonction comb !)
- ne pas mélanger les int et les long (hasardeux)
- utiliser directement des noms de variables tels que N et P plutôt que nbr1/nbr2 pour la lisibilité
- intégrer directement la condition N > P dans le while
 
Mais à part ces trucs là pour moi il fonctionne ton programme.

Reply

Marsh Posté le 04-03-2013 à 08:09:39    

essaie d'utiliser 40 et 50

Reply

Marsh Posté le 04-03-2013 à 08:10:48    

ou encore 20 et 30

Reply

Marsh Posté le 04-03-2013 à 08:22:28    

Je pense que ton problème c'est que tu sors de la limite autorisée par le long (je sais pas quelle est la valeur, ça dépend si c'est en 32bits ou 64bits, mais clairement ça permet pas de stocker une valeur telle que 30!).
Plutôt que de faire 30! / (20! * 10!), tu pourrais très bien faire :
30*29*28*27*26*25*24*23*22*21 / 10! (car le 30! se simplifie avec le 20!)
Mais tu pourras pas gérer tous les factoriels qu'on te demande, donc il faut que tu mettes des limites (que se passe-t-il si on te demande 1000! ?).

Reply

Marsh Posté le 04-03-2013 à 08:24:25    

Tu peux aussi essayer d'utiliser des unsigned long plutôt que des long ce qui permettrait d'avoir plus de valeurs possibles

Reply

Marsh Posté le 04-03-2013 à 09:04:51    

J'ai passé les types "long" en "long double" dans ton programme et ça a l'air de marcher avec les valeurs 20/30 ou 40/50. Si en plus tu rajoutes la simplification que j'ai indiquée (ne pas calculer 30!/(20! * 10!) mais 30*29*28*...*21/10!) tu peux gérer beaucoup plus de cas à mon avis.
Ne pas oublier de modifier le printf aussi, si tu passes en long double :

Code :
  1. printf("La combinaison de %d dans %d est : %Lf\n", P,N,combinaison(N,P));

Reply

Marsh Posté le 04-03-2013 à 11:05:10    

La factorielle ne marche que sur les entiers naturels, donc tu peux signer tes valeurs sur un unsigned long long int (uint64_t) pour avoir une valeur maximale de "18,446,744,073,709,551,615" (selon Wikipédia).


---------------
Perhaps you don't deserve to breathe
Reply

Sujets relatifs:

Leave a Replay

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