La création de tous les possibles k combinaisons de n objets en C++
Il y a n personnes numérotées de 1
à n
. Je dois écrire un code qui produit et l'impression de toutes les différentes combinaisons de k
les gens de ces n
. Veuillez expliquer l'algorithme utilisé pour cela.
- Voir stackoverflow.com/questions/127704/... pour une liste d'algorithmes. Je ne veux pas vous prendre la joie de les convertir en C++ 🙂
Vous devez vous connecter pour publier un commentaire.
Je suppose que vous vous posez à propos des combinaisons en combinatoire sens (c'est l'ordre des éléments n'a pas d'importance, de sorte
[1 2 3]
est le même que[2 1 3]
). L'idée est assez simple, si vous comprenez induction /récursivité: pour obtenir tous lesK
-élément de combinaisons, vous choisissez d'abord premier élément d'une combinaison de l'ensemble existant de gens, et ensuite vous "concaténer" cet élément de départ, avec toutes les combinaisons possibles deK-1
personnes produite à partir d'éléments que réussir l'élément initial.Comme un exemple, disons que nous voulons prendre toutes les combinaisons de 3 personnes à partir d'un ensemble de 5 personnes. Ensuite toutes les combinaisons possibles de 3 personnes peut être exprimée en fonction de toutes les combinaisons possibles de 2 personnes:
Voici le code C++ qui met en œuvre cette idée:
Et voici la sortie pour
N = 5, K = 3
:De Rosetta code
sortie
L'analyse et l'idée
Le point de l'ensemble est de jouer avec la représentation binaire des nombres
par exemple, le nombre 7 en binaire est 0111
Donc cette représentation binaire peut aussi être vu comme un liste d'affectation en tant que tel:
Pour chaque bit je si le bit est activé (j'.e est 1) signifie que le jeème élément est affecté d'autre pas.
Puis par simple calcul d'une liste d'consécutives nombres binaires et l'exploitation de la représentation binaire (qui peut être très rapide) donne un algorithme pour calculer toutes les combinaisons de N sur k.
La tri à la fin (de certaines implémentations) est pas nécessaire. C'est juste une façon de deterministicaly normaliser le résultat, j'.e pour les mêmes nombres (N, K) et même de l'algorithme de même ordre de combinaisons est retourné
Pour en savoir plus sur le nombre de représentations et de leur relation à des combinaisons, permutations, d'énergie (et d'autres choses intéressantes), ont un oeil à Combinatoire système de nombre , Factorielle du nombre de système
Si le nombre de jeu serait dans un rayon de 32, 64 ou une machine natif primitif de taille, alors vous pouvez le faire avec une simple manipulation de bits.
cet exemple appelle pretty_print() de la fonction par l'ordre du dictionnaire.
Par exemple. Vous voulez avoir 6C3 et en supposant que l'actuelle "combo" est 010110.
Évidemment, le prochain combo DOIT être 011001.
011001 est :
010000 | 001000 | 000001
010000 : supprimé en permanence 1s de côté LSB.
001000 : set 1 sur le côté de la permanence 1s de côté LSB.
000001 : déplacé en continu 1s de LSB vers la droite et retirez LSB bit.
cette obtient le plus bas 1.
ceci élimine en permanence 1s de LSB côté et de l'ensemble 1 sur le côté de celui-ci (dans le cas ci-dessus, 010000 | 001000)
cela vous donne en permanence à 1s de côté LSB (000110).
c'est pour "déplacé en continu 1s de LSB vers la droite et retirez LSB peu".
De sorte que le travail final est de OU de y au-dessus.
Un simple exemple concret :
résultat :
En Python, c'est implémentée comme itertools.combinaisons
https://docs.python.org/2/library/itertools.html#itertools.combinations
En C++, par exemple la fonction de combinaison pourrait être mis en œuvre en fonction de permutation de la fonction.
L'idée de base est d'utiliser un vecteur de taille n, et définir seul élément de k à 1 à l'intérieur, puis toutes les combinaisons de nchoosek pourrait obtenus par la collecte de k éléments dans chaque permutation.
Bien qu'il pourrait ne pas être le moyen le plus efficace exigent un grand espace, comme la combinaison est généralement un très grand nombre. Il est préférable d'être mis en œuvre comme un générateur ou mettre les codes de travail dans do_sth().
Exemple de Code:
et la sortie est
Cette solution est en fait un doublon avec
Générer combinaisons en c++
do_sth
?J'ai écrit une classe en C# pour gérer des fonctions pour travailler avec le coefficient binomial, qui est le type de problème que votre problème relève de. Il effectue les tâches suivantes:
Sorties de tous les K-index dans un beau format pour tout N de choisir K pour un fichier. Le K-index peut être substitué avec plus descriptif, les cordes ou les lettres. Cette méthode permet de résoudre ce type de problème tout à fait banale.
Convertit le K-index de l'index approprié d'une entrée dans la triés coefficient binomial table. Cette technique est beaucoup plus rapide que les plus âgés publié des techniques qui s'appuient sur l'itération. Il le fait en utilisant une propriété mathématique inhérente dans le Triangle de Pascal. Mon livre parle de cela. Je crois que je suis le premier à découvrir et publier cette technique.
Convertit l'indice triés coefficient binomial tableau correspondant de la K-index. Je crois qu'il est également plus rapide que les autres solutions.
Utilise Marque Dominus méthode pour calculer le coefficient binomial, ce qui est beaucoup moins susceptibles de déborder et travaille avec de plus grands nombres.
La classe est écrit en .NET C# et fournit un moyen de gérer les objets en rapport avec le problème (le cas échéant) à l'aide d'une liste générique. Le constructeur de cette classe prend une valeur booléenne appelée InitTable que lorsque la volonté réelle de créer une liste générique pour contenir les objets gérés. Si cette valeur est fausse, alors il ne va pas créer la table. La table n'a pas besoin d'être créé afin d'effectuer les 4 méthodes ci-dessus. Méthodes d'accès sont fournis pour accéder à la table.
Il est associé à une classe de test qui montre comment utiliser la classe et ses méthodes. Il a été testé avec les 2 cas, et il n'y a pas de bugs connus.
À lire sur cette classe et télécharger le code, voir Tablizing Le Binôme Coeffieicent.
Il devrait être assez simple à port la classe au cours de C++.
La solution à votre problème consiste à générer le K-index pour chaque N choisir K cas. Par exemple:
La OutputKIndexes méthode peut également être utilisée à la sortie de la K-index d'un fichier, mais il va utiliser un fichier différent pour chaque N choisir K cas.
Ici est un algorithme que j'ai trouvé pour résoudre ce problème. Vous devriez être capable de le modifier pour qu'il fonctionne avec votre code.
Vous pouvez voir une explication de la façon dont il fonctionne ici.
Derrière le lien ci-dessous est un générique de C# réponse à ce problème: Comment faire pour formater toutes les combinaisons à partir d'une liste d'objets. Vous pouvez limiter les résultats que pour la longueur de k assez facilement.
https://stackoverflow.com/a/40417765/2613458
Il peut aussi être fait en utilisant les retours en arrière par le maintien d'une visité tableau.