Nombre de combinaisons (N choisir R) dans C++
Ici, j'essaie d'écrire un programme en C++ pour trouver de la RCN. Mais j'ai un problème dans le résultat. Il n'est pas correct. Pouvez-vous m'aider à trouver ce que l'erreur est dans le programme?
#include <iostream>
using namespace std;
int fact(int n){
if(n==0) return 1;
if (n>0) return n*fact(n-1);
};
int NCR(int n,int r){
if(n==r) return 1;
if (r==0&&n!=0) return 1;
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
};
int main(){
int n; //cout<<"Enter A Digit for n";
cin>>n;
int r;
//cout<<"Enter A Digit for r";
cin>>r;
int result=NCR(n,r);
cout<<result;
return 0;
}
Votre formule est mal, il a
fact(n-1)
dans le numérateur et le dénominateur (ils annuler).OriginalL'auteur Hams | 2012-02-17
Vous devez vous connecter pour publier un commentaire.
Votre formule est totalement faux, c'est censé être
fact(n)/fact(r)/fact(n-r)
, mais qui est à son tour une voie très inefficace pour le calculer.Voir Un calcul rapide de multi-catégorie nombre de combinaisons et surtout mes commentaires sur cette question. (Oh, et merci de revenir sur cette question afin que je puisse répondre correctement)
Le single split cas est en fait très facile à manipuler:
Démo: http://ideone.com/aDJXNO
Si le résultat ne convient pas, vous pouvez calculer la somme des logarithmes et obtenir le nombre de combinaisons inexactly comme un double. Ou l'utilisation d'une précision arbitraire entier de la bibliothèque.
Je suis en train de mettre ma solution à l'autre, étroitement liés à la question ici, parce que ideone.com a été de perdre des extraits de code dernièrement, et l'autre question est toujours fermé à de nouvelles réponses.
OriginalL'auteur Ben Voigt
La définition de N choisir R est de calculer les deux produits et de diviser l'un avec l'autre,
(N * N-1 * N-2 * ... * N-R+1) /(1 * 2 * 3 * ... * R)
Cependant, la multiplication peut devenir trop volumineux vraiment rapide et de débordement de type de données existant. La mise en œuvre truc, c'est de réorganiser la multiplication et de la division,
(N)/1 * (N-1)/2 * (N-2)/3 * ... * (N-R+1)/R
Il est garanti qu'à chaque étape les résultats est divisible (pour n en continu de numéros, l'un d'eux doit être divisible par n, donc est le produit de ces nombres).
Par exemple, pour N en choisir 3, au moins un des N, N-1, N-2 est un multiple de 3, et pour N choisir 4, au moins un des N, N-1, N-2, N-3, N soit un multiple de 4.
C++ code donné ci-dessous.
res
êtrelong
à tous?Juste pour les situations qui le res *= n - k + 1 étape de dépassement avant la division arrive.
OriginalL'auteur Steven
Une belle façon de mettre en œuvre des n-choisissez-k est à la base pas sur les factorielles, mais sur une "la hausse des produits de la fonction" qui est étroitement liée à la factorielle.
La rising_product(m, n) multiplie ensemble m * (m + 1) * (m + 2) * ... * n, avec des règles pour la gestion des divers cas de coin, comme n >= m, ou n <= 1:
Voir ici pour une mise en œuvre nCk ainsi que les nPk en tant que fonctions intrinsèques dans un langage de programmation interprété écrit en C:
Ce code ne nécessite pas d'utiliser des opérateurs comme
+
et<
car il est de type générique (le typeval
représente une valeur de toutes les sortes, tels que divers types de nombres, y compris "bignum" entiers) et parce que c'est écrit en C (pas de surcharge), et parce que c'est la base pour un Lisp comme les langues qui n'ont pas infix syntaxe.En dépit de cela, ce n-choisissez-k de la mise en œuvre a une structure simple qui est facile à suivre.
Légende:
le
: inférieur ou égal;ge
: supérieure ou égale;trunc
: la troncation de la division;plus
: plus,mul
: multiplication,one
: unval
tapé constante pour le numéro un.OriginalL'auteur Kaz
la ligne
devrait être
ou même
fact(n-r)
doit être un diviseur, pas un facteur multiplicatif.oups, oui, bien sûr... Corrigé. Merci!
OriginalL'auteur Korchkidu
Utilisation
double
au lieu deint
.Mise à JOUR:
Votre formule est également faux. Vous devez utiliser
fact(n)/fact(r)/fact(n-r)
Oui! Je n'ai pas soin de vérifier la formule, parce que l'utilisation
int
serait également produire des résultats erronés.Même en utilisant
double
n'est pas une très bonne approche. Essayez de calculer6000 choose 3
. Il s'intègre facilement dans un 32 bitsint
, mais l'utilisation de cette formule et du double échouer lamentablement.oups... je voulais dire
600 choose 3
s'adapte facilement.6000 choose 3
ne fait pas.OriginalL'auteur Pulkit Goyal
c'est de la référence à ne pas obtenir un temps limite dépassé lors de la résolution de rcn dans la compétitivité et de la programmation,je suis l'affichage de ce qu'il sera utile à u comme vous l'avez déjà obtenu réponse pour ur question,
Obtenir la factorisation du coefficient binomial est probablement le moyen le plus efficace pour le calculer, surtout si la multiplication est cher. C'est certainement vrai pour le problème de calcul de factorielle (voir Cliquez ici par exemple).
Ici est un simple algorithme basé sur le Crible d'Eratosthène qui calcule la factorisation en nombres premiers. L'idée est d'aller à travers les nombres premiers que vous trouvez à l'aide de la passoire, mais aussi pour calculer le nombre de leur multiples tomber dans l'intervalle [1, k] et [n-k+1,n]. Le Tamis est essentiellement un O(n \log \log n) de l'algorithme, mais il n'y a pas de multiplication de fait. Le nombre de multiplications nécessaires une fois la factorisation en nombres premiers est, au pire, O\left(\frac{n \log \log n}{\log n}\right) et il y a probablement des façons plus rapides que ça.
OriginalL'auteur