Voici la manière très stupide:
def divisorGenerator(n):
for i in xrange(1,n/2+1):
if n%i == 0: yield i
yield n
Le résultat que j'aimerais obtenir est similaire à celui-ci, mais j'aimerais un algorithme plus intelligent (celui-ci est trop lent et stupide :-)
Je peux trouver assez rapidement les facteurs premiers et leur multiplicité. J'ai un générateur qui génère un facteur de cette manière:
(facteur1, multiplicité1)
(facteur2, multiplicité2)
(facteur3, multiplicité3)
et ainsi de suite ...
c'est-à-dire la sortie de
for i in factorGenerator(100):
print i
est:
(2, 2)
(5, 2)
Je ne sais pas à quel point cela est utile pour ce que je veux faire (je l'ai codé pour d'autres problèmes), de toute façon j'aimerais une façon plus intelligente de faire
for i in divisorGen(100):
print i
sortie ceci:
1
2
4
5
10
20
25
50
100
MISE À JOUR: Un grand merci à Greg Hewgill et sa "manière intelligente" :) Le calcul de tous les diviseurs de 100000000 a pris 0,01s avec son chemin contre les 39 que la manière stupide a pris sur ma machine, très cool: D
MISE À JOUR 2: Arrêtez de dire que c'est un double de ce message. Le calcul du nombre de diviseurs d'un nombre donné n'a pas besoin de calculer tous les diviseurs. C'est un problème différent, si vous pensez que ce n'est pas le cas, cherchez "Fonction Diviseur" sur wikipedia. Lisez les questions et la réponse avant de poster, si vous ne comprenez pas quel est le sujet, n'ajoutez simplement pas les réponses inutiles et déjà données.
Réponses:
Compte tenu de votre
factorGenerator
fonction, voici undivisorGen
qui devrait fonctionner:L'efficacité globale de cet algorithme dépendra entièrement de l'efficacité du
factorGenerator
.la source
Pour développer ce que Shimi a dit, vous ne devriez exécuter votre boucle que de 1 à la racine carrée de n. Ensuite, pour trouver la paire, faites
n / i
, et cela couvrira tout l'espace du problème.Comme on l'a également noté, il s'agit d'un problème NP ou «difficile». La recherche exhaustive, comme vous le faites, est à peu près aussi bonne que possible pour obtenir des réponses garanties. Ce fait est utilisé par les algorithmes de cryptage et autres pour aider à les sécuriser. Si quelqu'un résolvait ce problème, la plupart sinon la totalité de nos communications «sécurisées» actuelles seraient rendues non sécurisées.
Code Python:
Ce qui devrait afficher une liste comme:
la source
Bien qu'il existe déjà de nombreuses solutions à cela, je dois vraiment poster ceci :)
Celui-ci est:
Code:
la source
while i*i <= nn
parwhile i <= limit
, oùlimit = math.sqrt(n)
Je pense que vous pouvez vous arrêter au
math.sqrt(n)
lieu de n / 2.Je vais vous donner un exemple pour que vous puissiez le comprendre facilement. Maintenant , le
sqrt(28)
est5.29
doncceil(5.29)
sera 6. Je si je vais arrêter à 6 alors je peux obtenir tous les diviseurs. Comment?Voir d'abord le code, puis voir l'image:
Maintenant, voyez l'image ci-dessous:
Disons que je l' ai déjà ajouté
1
à ma liste de diviseurs et je commence pari=2
siDonc à la fin de toutes les itérations, comme j'ai ajouté le quotient et le diviseur à ma liste, tous les diviseurs de 28 sont remplis.
Source: Comment déterminer les diviseurs d'un nombre
la source
math.sqrt(n) instead of n/2
est obligatoire pour l'éléganceJ'aime la solution de Greg, mais j'aurais aimé qu'elle ressemble plus à Python. Je pense que ce serait plus rapide et plus lisible; donc après un certain temps de codage, je suis sorti avec ceci.
Les deux premières fonctions sont nécessaires pour faire le produit cartésien de listes. Et peut être réutilisé dès que ce problème survient. Au fait, j'ai dû le programmer moi-même, si quelqu'un connaît une solution standard pour ce problème, n'hésitez pas à me contacter.
"Factorgenerator" renvoie maintenant un dictionnaire. Et puis le dictionnaire est introduit dans des "diviseurs", qui l'utilisent pour générer d'abord une liste de listes, où chaque liste est la liste des facteurs de la forme p ^ n avec p premier. Ensuite, nous faisons le produit cartésien de ces listes, et nous utilisons finalement la solution de Greg pour générer le diviseur. Nous les trions et les retournons.
Je l'ai testé et il semble être un peu plus rapide que la version précédente. Je l'ai testé dans le cadre d'un programme plus vaste, donc je ne peux pas vraiment dire à quel point c'est plus rapide.
Pietro Speroni (pietrosperoni dot it)
PS, c'est la première fois que je poste sur stackoverflow. J'attends vos commentaires avec impatience.
la source
Voici un moyen intelligent et rapide de le faire pour les nombres jusqu'à et autour de 10 ** 16 en pur Python 3.6,
la source
Adapté de CodeReview , voici une variante qui fonctionne avec
num=1
!la source
NameError: global name 'prime_factors' is not defined
. Aucune des autres réponses, ni la question initiale, ne définit ce que cela fait.Je vais juste ajouter une version légèrement révisée d'Anivarth (car je crois que c'est la plus pythonique) pour référence future.
la source
Ancienne question, mais voici mon avis:
Vous pouvez utiliser un proxy avec:
Remarque: pour les langues qui prennent en charge, cela peut être récursif de queue.
la source
En supposant que la
factors
fonction renvoie les facteurs de n (par exemple,factors(60)
retourne la liste [2, 2, 3, 5]), voici une fonction pour calculer les diviseurs de n :la source
Voici ma solution. Cela semble stupide mais fonctionne bien ... et j'essayais de trouver tous les diviseurs appropriés, donc la boucle a commencé à partir de i = 2.
la source
Si vous ne vous souciez que de l'utilisation de la compréhension de liste et que rien d'autre ne compte pour vous!
la source
Si votre PC a des tonnes de mémoire, une seule ligne brute peut être assez rapide avec numpy:
Prend moins de 1s sur mon PC lent.
la source
Ma solution via la fonction générateur est:
la source
la source
Pour moi, cela fonctionne bien et est également propre (Python 3)
Pas très rapide mais retourne les diviseurs ligne par ligne comme vous le souhaitez, vous pouvez également faire list.append (n) et list.append (nombre) si vous le souhaitez vraiment
la source