Algorithme pour trouver Plus grand facteur premier d'un certain nombre
Quelle est la meilleure approche pour calculer le plus grand facteur premier d'un nombre?
Je pense que le plus efficace serait le suivant:
- Trouver plus bas nombre premier qui divise proprement
- Vérifier si le résultat de la division est le premier
- Si non, trouver plus bas suivant
- Aller à 2.
Je suis fonder cette hypothèse qu'il soit plus facile de calculer les petits facteurs premiers. Est-ce vrai? Quelles sont les autres démarches dois-je rechercher dans?
Edit: j'ai compris que ma démarche est vaine si il y a plus de 2 facteurs premiers dans le jeu, depuis l'étape 2 échoue lorsque le résultat est un produit de deux nombres premiers, donc un algorithme récursif est nécessaire.
Modifier à nouveau: Et maintenant, je ai réalisé que ce ne soit encore du travail, car le dernier trouvé le premier nombre doit être le plus haut, donc tout autre essai de la non-le premier résultat de l'étape 2 aurait pour résultat un plus petit nombre premier.
- Mon approche a été de: (1) diviser les grandes, nombre par 2; (2) vérifier si le grand nombre divise de manière égale; 3) si oui, vérifier si le divise par 2 le nombre est premier. Si elle l'est, le retour. (4) Sinon, il suffit de soustraire 1 de l'divisé par 2 nombre de, retour à l'étape 3.
1.
trouver n'importe quel nombre qui divise clairement (pour i = 2 à int(sqr(num)) )2.
diviser par le nombre (num = num/i) et se répètent jusqu'à ce que rien n'est trouvé dans 1.'s de l'intervalle de3.
num est le plus grand facteur de- Nous pouvons Diviser avec de petits nombres premiers, et celui qui est, enfin, à gauche, est le Plus grand Facteur Premier (je crois)
Vous devez vous connecter pour publier un commentaire.
En fait il y a plusieurs manières plus efficaces de trouver des facteurs de grands nombres (pour les plus petits division de première instance qui fonctionne plutôt bien).
Une méthode qui est très rapide si le nombre d'entrée a deux facteurs très près de sa racine carrée est connu comme Factorisation de Fermat. Il rend l'utilisation de l'identité N = (a + b)(a - b) = a^2 - b^2 et est facile à comprendre et à mettre en œuvre. Malheureusement, il n'est pas très rapide en général.
Le plus connu de la méthode de factorisation de nombres jusqu'à 100 chiffres est le Le crible quadratique. Comme un bonus, une partie de l'algorithme est facile à faire avec le traitement en parallèle.
Encore un autre algorithme, j'ai entendu parler de est Pollard Rho algorithme. Ce n'est pas aussi efficace que le Crible Quadratique en général, mais semble être le plus facile à mettre en œuvre.
Une fois que vous avez décidé sur la façon de diviser un nombre à deux facteurs, ici, c'est l'algorithme le plus rapide que je peux penser à trouver le plus grand facteur premier d'un nombre:
Créer une file d'attente de priorité qui, initialement, stocke le nombre lui-même. À chaque itération, vous supprimez le nombre le plus élevé de la file d'attente, et de tenter de diviser en deux facteurs (ne permettant pas de 1 pour être l'un de ces facteurs, bien sûr). Si cette étape échoue, le nombre est premier et vous avez votre réponse! Sinon, vous ajoutez les deux facteurs dans la file d'attente et répétez.
Voici le meilleur algorithme que je connais (en Python)
La méthode ci-dessus fonctionne dans
O(n)
dans le pire des cas (lorsque l'entrée est un nombre premier).EDIT:
Ci-dessous est la
O(sqrt(n))
version, comme le suggère le commentaire. Voici le code, une fois de plus.O(sqrt(n))
dans le pire des cas" - Non, il s'exécute dansO(n)
dans le pire des cas (par exemple lorsquen
est premier.)O(n)
pour le premier les valeurs de n.d = d + 1
être ignoré pour les nombres qui ne sont pas une prime?n /= d
. Il supprime le premier facteur d de n pour les calculs ultérieurs dans la boucle.d = d + 1
nous amène à la force brute tous les numéros d <= sqrt(n). (Si d est composite, alors n ne peut pas toujours être divisible par d, car nous avons déjà supprimé tous les facteurs de < d. Mais cet algorithme tente toujours de la division de première instancewhile n % d == 0
de toute façon, même si d est composite. C'est pourquoi c'est très inefficace. Plus d arrive, le plus probablement, il est en composite et donc n'a pas besoin d'être testé.)Ma réponse est basée sur Triptyque's, mais améliore beaucoup de choses sur elle. Il est basé sur le fait qu'au-delà de 2 et 3, tous les nombres premiers de la forme 6n-1 ou 6n+1.
J'ai récemment écrit un article du blog expliquant comment cet algorithme fonctionne.
Je crois qu'une méthode dans laquelle il n'est pas nécessaire pour un test de primalité (et pas de tamis de construction) permettrait de courir plus vite qu'un autre qui ne les utiliser. Si c'est le cas, c'est probablement l'algorithme le plus rapide ici.
while (multOfSix - 1 <= n)
Code JavaScript:
Exemple D'Utilisation:
Voici un exemple de code:
Tous les numéros peut être exprimé comme le produit de nombres premiers, par exemple:
Vous pouvez trouver ces simplement en commençant à 2 et tout simplement de continuer à se diviser jusqu'à ce que le résultat n'est pas un multiple de votre numéro:
utilisant cette méthode, vous n'avez pas à calculer les nombres premiers: ils vont tous être des nombres premiers, basée sur le fait que vous avez déjà des effets industriels le nombre autant que possible, tous les numéros précédents.
currFactor = 3513642
, nous savons que 12345678987667 est premier, et à la renvoyer à la réponse. Au lieu de cela, ce code va continuer l'énumération jusqu'à 12345678987667 lui-même. C'est 3,513,642 x plus lentement que nécessaire.while
boucle passera pari
valeurs de2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5
. Tous 60 itérations. Mais pour (10^12+39) il y aura (10^12+38) itérations,i=2,3,4,5,6,...,10^12+39
. Même si 10^10 ops prendre une seconde, 10^12 va prendre 100 secondes. Mais seulement 10^6 itérations sont vraiment nécessaires, et si 10^10 ops prendre un deuxième, 10^6 prendrait 1/10,000 ème de seconde.long n = 2*1000000000039L
? Cela fonctionne aussi vite qu'il le devrait? (aussi, pouvez-vous simplifier votre code à l'aide d'unreturn;
déclaration?). (si vous voulez me demander d'arrêter de vous secoue, dis-donc ;))Similaire à @Triptyque de réponse, mais aussi différents. Dans cet exemple de liste ou un dictionnaire n'est pas utilisé. Le Code est écrit en Ruby
La solution la plus simple est une paire de mutuellement récursives fonctions.
La première fonction produit de tous les nombres premiers:
La seconde fonction retourne les facteurs premiers d'un nombre donné
n
dans l'ordre croissant.n
.Le plus grand facteur premier de
n
est le dernier numéro donné par la deuxième fonction.Cet algorithme nécessite un paresseux liste ou une langue (ou une structure de données) avec appel par nécessité sémantique.
Pour plus de précisions, voici un (inefficace) de la mise en œuvre de la ci-dessus en Haskell:
Faire de ce plus vite est juste une question d'être plus intelligent sur la détection des nombres qui sont le premier et/ou des facteurs de
n
, mais l'algorithme reste le même.Il y a quelques modulo tests de superflu, que n ne peut jamais être divisé par 6 si tous les facteurs 2 et 3 ont été supprimés. Vous ne pouviez vous permettre de nombres premiers pour moi, ce qui est démontré dans plusieurs autres réponses ici.
Vous pourrait en fait s'entrelacer le crible d'Eratosthène ici:
à sqrt(n).
de i jusqu'à la nouvelle sqrt(n) de ne pas
le premier, et d'utiliser une boucle while à la place.
la liste.
Voir aussi cette question.
Je suis conscient que ce n'est pas une solution rapide. L'affichage que l'espérons, plus facile à comprendre lente de la solution.
Python approche Itérative par la suppression de tous les facteurs premiers du nombre
Je suis en utilisant un algorithme, qui continue à diviser le nombre par lui, l'actuel Premier Facteur.
Ma Solution en python 3 :
D'entrée :
10
Sortie :
5
D'entrée :
600851475143
Sortie :
6857
Ici est une tentative de ma part en c#. La dernière impression est le plus grand facteur premier de le nombre. J'ai vérifié et il fonctionne.
Calcule le plus grand facteur premier d'un nombre en utilisant la récursivité en C++. Le travail de la code est expliqué ci-dessous:
Voici ma démarche pour calculer rapidement le plus grand facteur premier.
Il est basé sur le fait que modifié
x
ne contient pas de non-facteurs premiers. Pour y parvenir, nous diviserx
dès qu'un facteur est trouvé. Ensuite, la seule chose qui reste est de retour le facteur le plus important. Il serait déjà premier.Le code (Haskell):
Le C++ suivant l'algorithme n'est pas le meilleur, mais il fonctionne pour les nombres inférieurs à un milliard de dollars et son assez rapide
Trouvé cette solution sur le web par "James Wang"
Le premier facteur à l'aide de tamis :
Il me semble que l'étape 2 de l'algorithme donné ne va pas du tout être efficace, une approche. Vous n'avez aucune raison de croire qu'il est premier.
Aussi, la réponse précédente suggère le Crible d'Eratosthène est absolument mauvais. Je viens d'écrire deux programmes de facteur 123456789. L'une repose sur le Tamis, l'une repose sur les éléments suivants:
Cette version a été 90x plus rapide que le Tamis.
La chose est, sur les processeurs modernes du type d'opération à des questions beaucoup moins que le nombre d'opérations, pour ne pas mentionner que l'algorithme ci-dessus peut s'exécuter dans le cache, le Tamis peuvent pas. Le Tamis utilise beaucoup d'opérations de suppression de tous les numéros composés.
Note, également, que mon divisant les facteurs comme ils sont identifiés réduit l'espace qui doit être testé.
Calculer une liste de stocker des nombres premiers de la première, par exemple, 2 3 5 7 11 13 ...
Chaque fois que vous premier factoriser un nombre, utilisez la mise en œuvre par le Triptyque mais en itérant cette liste de nombres premiers plutôt que d'entiers.
Avec Java:
Pour
int
valeurs:Pour
long
valeurs:Ce n'est probablement pas toujours plus rapide, mais plus optimiste à ce sujet, vous trouverez un grand diviseur premier:
N
est votre numéro dereturn(N)
Sqrt(N)
N is divisible by Prime
puisReturn(Prime)
Edit: Dans l'étape 3, vous pouvez utiliser le Crible d'Eratosthène ou un Tamis de l'Atkins, ou ce que vous voulez, mais par lui-même le tamis de ne pas vous trouver le plus grand facteur premier. (C'est pourquoi je ne voudrais pas choisir SQLMenace post comme une réponse officielle...)
Je pense qu'il serait bon de les stocker quelque part tous les possibles de nombres premiers plus petit que n et juste parcourir pour trouver le plus grand divisior. Vous pouvez obtenir des nombres premiers de prime-numbers.org.
Bien sûr, je suppose que votre numéro n'est pas trop grande 🙂
Pas le plus rapide mais ça marche!!!
Ici est la même fonction@Triptyque fourni comme un générateur, qui a également été légèrement simplifié.
le max le premier peut alors être trouvé à l'aide de:
et une liste de facteurs à l'aide de: