किसी संख्या का सबसे बड़ा मुख्य कारक खोजने के लिए एल्गोरिथम


183

किसी संख्या के सबसे बड़े अभाज्य गुणक की गणना करने के लिए सबसे अच्छा तरीका क्या है?

मुझे लगता है कि सबसे कुशल निम्नलिखित होगा:

  1. सबसे कम अभाज्य संख्या ज्ञात करें जो सफाई से विभाजित हो
  2. जांच करें कि क्या विभाजन का परिणाम प्रमुख है
  3. यदि नहीं, तो अगले निम्नतम खोजें
  4. 2 पर जाएं।

मैं इस धारणा को आधार बना रहा हूं कि छोटे प्रमुख कारकों की गणना करना आसान हो। क्या यह सही है? मुझे किन अन्य दृष्टिकोणों पर ध्यान देना चाहिए?

संपादित करें: मुझे अब पता चला है कि मेरा दृष्टिकोण निरर्थक है अगर खेल में 2 से अधिक प्रमुख कारक हैं, क्योंकि चरण 2 विफल रहता है जब परिणाम दो अन्य primes का उत्पाद होता है, इसलिए पुनरावर्ती एल्गोरिथ्म की आवश्यकता होती है।

फिर से संपादित करें: और अब मैंने महसूस किया है कि यह अभी भी काम करता है, क्योंकि अंतिम पाया गया अभाज्य संख्या सबसे अधिक है, इसलिए चरण 2 से गैर-प्राइम परिणाम के किसी भी आगे के परीक्षण के परिणामस्वरूप एक छोटा प्राइम होगा।


मेरा दृष्टिकोण था: (1) 2 से बड़े, संभव संख्या को विभाजित करें; (2) जाँच करें कि क्या बड़ी संख्या समान रूप से विभाजित होती है; (३) यदि हां, तो जांच लें कि विभाजित २ संख्या प्रधान है या नहीं। यदि यह है, तो इसे वापस करें। (४) एलीस, १ से विभाजित होकर १ नंबर, २ पर लौटना। ३
केविन मेरेडिथ

1.किसी भी संख्या है कि विभाजित स्पष्ट रूप से (i = 2 को पूर्णांक (sqr (संख्या)) के लिए) लगता है 2.कि संख्या से विभाजित (num = संख्या / i) और कुछ भी नहीं है, जब तक की पुनरावृत्ति में पाया जाता है 1. के अंतराल 3. संख्या सबसे बड़ा कारक है
user3819867

1
हम छोटे अपराधों के साथ विभाजित कर सकते हैं, और जो अंततः बचा है, वह सबसे बड़ा प्रधानमंत्री कारक है (मुझे लगता है)

जवाबों:


134

वास्तव में बड़ी संख्या के कारकों को खोजने के लिए कई और अधिक कुशल तरीके हैं (छोटे लोगों के लिए परीक्षण प्रभाग यथोचित रूप से काम करता है)।

एक विधि जो बहुत तेज़ है यदि इनपुट नंबर के दो कारक हैं जो इसके वर्गमूल के बहुत करीब है, जिसे Fermat कारक के रूप में जाना जाता है । यह पहचान N = (a + b) (a - b) = a ^ 2 - b ^ 2 का उपयोग करता है और समझने और लागू करने में आसान होता है। दुर्भाग्य से यह सामान्य रूप से बहुत तेज नहीं है।

100 अंकों तक लंबी संख्याओं को फैक्टर करने के लिए सबसे अच्छी ज्ञात विधि द्विघात चलनी है । एक बोनस के रूप में, एल्गोरिथ्म का हिस्सा आसानी से समानांतर प्रसंस्करण के साथ किया जाता है।

फिर भी एक और एल्गोरिथ्म जो मैंने सुना है वह है पोलार्ड का आरएच एल्गोरिथ्म । यह सामान्य रूप में द्विघात चलनी के रूप में कुशल नहीं है लेकिन इसे लागू करना आसान लगता है।


एक बार जब आपने किसी संख्या को दो कारकों में विभाजित करने का निर्णय लिया, तो यहां सबसे तेज़ एल्गोरिथ्म है जो मैं किसी संख्या के सबसे बड़े कारक को खोजने के लिए सोच सकता हूं:

एक प्राथमिकता कतार बनाएँ जो शुरू में ही नंबर को स्टोर करती है। प्रत्येक पुनरावृत्ति, आप कतार से उच्चतम संख्या निकालते हैं, और इसे दो कारकों में विभाजित करने का प्रयास करते हैं (1 को उन कारकों में से एक होने की अनुमति नहीं देता है, निश्चित रूप से)। यदि यह चरण विफल हो जाता है, तो संख्या अभाज्य है और आपके पास आपका उत्तर है! अन्यथा आप दो कारकों को कतार में जोड़ते हैं और दोहराते हैं।


3
पोलार्ड आरएच और अण्डाकार वक्र विधि द्विघात चलनी की तुलना में आपकी संख्या के छोटे प्रमुख कारकों से छुटकारा पाने में बहुत बेहतर है। QS के पास समान रनटाइम संख्या के बारे में नहीं है। कौन सा दृष्टिकोण तेज है यह इस बात पर निर्भर करता है कि आपका नंबर क्या है; QS हार्ड-टू-फैक्टर नंबर को तेजी से क्रैक करेगा जबकि rho और ECM आसानी से-टू-फैक्टर नंबर को तेजी से क्रैक करेगा।
17

द्विघात परिवर्तन सुझाव के लिए धन्यवाद। मुझे अपने ग्राहकों में से एक के लिए इसे लागू करने की आवश्यकता थी, जो शुरुआती संस्करण मैं आया था, उसके सवाल में @mercutio ने जो कुछ कहा था, उसकी तर्ज पर कुछ था। द्विघात समाधान वह है जो मेरे ग्राहक के टूल को अब math.tools/calculator/prime-factors पर पावर कर रहा है
dors

यदि इस समस्या को हल करने का एक कुशल तरीका है, तो क्या इसका मतलब यह नहीं है कि वेब एन्क्रिप्शन सुरक्षित नहीं है?
BKSpurgeon

141

यहाँ सबसे अच्छा एल्गोरिथ्म मुझे पता है (पायथन में)

def prime_factors(n):
    """Returns all the prime factors of a positive integer"""
    factors = []
    d = 2
    while n > 1:
        while n % d == 0:
            factors.append(d)
            n /= d
        d = d + 1

    return factors


pfs = prime_factors(1000)
largest_prime_factor = max(pfs) # The largest element in the prime factor list

उपरोक्त विधि O(n)सबसे खराब स्थिति में चलती है (जब इनपुट एक अभाज्य संख्या है)।

EDIT:
नीचे O(sqrt(n))संस्करण है, जैसा कि टिप्पणी में सुझाया गया है। यहाँ कोड है, एक बार और।

def prime_factors(n):
    """Returns all the prime factors of a positive integer"""
    factors = []
    d = 2
    while n > 1:
        while n % d == 0:
            factors.append(d)
            n /= d
        d = d + 1
        if d*d > n:
            if n > 1: factors.append(n)
            break
    return factors


pfs = prime_factors(1000)
largest_prime_factor = max(pfs) # The largest element in the prime factor list

11
वोट करने से पहले कृपया इस कोड को पढ़ें और / या चलाएं। यह बढ़िया काम करता है। बस कॉपी और पेस्ट करें। के रूप में लिखा Prime_factors (1000) वापस आ जाएगा [2,2,2,5,5,5], जिसे 2 ^ 3 * 5 ^ 3 के रूप में व्याख्या किया जाना चाहिए, मुख्य कारक।
त्रिफलक

11
" O(sqrt(n))सबसे खराब स्थिति में चलता है " - नहीं, यह O(n)सबसे खराब स्थिति में चलता है (जैसे कि जब nप्राइम होता है।)
शेल्डन एल। कूपर

16
इसे बनाने में आसान O (sqrt (n)), आप बस लूप को रोकते हैं जब d * d> n, और यदि n> 1 इस बिंदु पर होता है, तो इसका मान अभाज्य कारकों की सूची में जोड़ा जाना चाहिए।
सुमुदु फर्नांडो

5
क्या इसका कोई नाम है?
फोर्थिंकर

11
चूँकि 2 ही एकमात्र अभाज्य संख्या है, इसलिए प्रत्येक बार 1 जोड़ने के बजाय, आप d = 2 के लिए अलग से पुनरावृति कर सकते हैं और फिर इसे 1 से बढ़ा सकते हैं और फिर d = 3 के बाद आप 2 से बढ़ा सकते हैं। इसलिए यह संख्या घट जाएगी पुनरावृत्तियों का ... :)
tailor_raj

18

मेरा जवाब Triptych के पर आधारित है , लेकिन इस पर बहुत सुधार होता है। यह इस तथ्य पर आधारित है कि 2 और 3 से परे, सभी अभाज्य संख्याएँ 6n-1 या 6n + 1 हैं।

var largestPrimeFactor;
if(n mod 2 == 0)
{
    largestPrimeFactor = 2;
    n = n / 2 while(n mod 2 == 0);
}
if(n mod 3 == 0)
{
    largestPrimeFactor = 3;
    n = n / 3 while(n mod 3 == 0);
}

multOfSix = 6;
while(multOfSix - 1 <= n)
{
    if(n mod (multOfSix - 1) == 0)
    {
        largestPrimeFactor = multOfSix - 1;
        n = n / largestPrimeFactor while(n mod largestPrimeFactor == 0);
    }

    if(n mod (multOfSix + 1) == 0)
    {
        largestPrimeFactor = multOfSix + 1;
        n = n / largestPrimeFactor while(n mod largestPrimeFactor == 0);
    }
    multOfSix += 6;
}

मैंने हाल ही में एक ब्लॉग लेख लिखा है जिसमें बताया गया है कि यह एल्गोरिदम कैसे काम करता है।

मैं कहता हूं कि ऐसी विधि जिसमें प्राणशक्ति के लिए परीक्षण की आवश्यकता नहीं है (और कोई चलनी निर्माण) एक से अधिक तेजी से चलेगी जो उन का उपयोग करता है। अगर ऐसा है, तो यह संभवतः यहाँ का सबसे तेज़ एल्गोरिथम है।


12
आप वास्तव में इस विचार को और भी आगे ले जा सकते हैं, उदाहरण के लिए 2,3,5 से परे सभी प्राइम्स फॉर्म 30n + k (n> = 0) के होते हैं, जहाँ k केवल 1 और 29 के बीच उन मानों को लेता है जो 2,3 से विभाज्य नहीं हैं या 5, यानी 7,11,13,17,19,23,29। यहां तक ​​कि आपके पास 2 * 3 * 5 * 7 * ... * n + k में से प्रत्येक के बाद पाए जाने वाले हर कुछ अपराधों के बाद यह गतिशील रूप से अनुकूल हो सकता है, जहां k को इनमें से किसी भी primes द्वारा विभाज्य नहीं होना चाहिए (ध्यान दें कि सभी संभव कश्मीर की आवश्यकता नहीं है प्राइम हो सकता है, जैसे कि 210n + k के लिए आपको 121 को शामिल करना होगा, अन्यथा आप 331 को मिस करेंगे )
टोबीस किन्ज़लर

2
मुझे लगता है कि यह होना चाहिएwhile (multOfSix - 1 <= n)
नादर घनबरी

8

जावास्क्रिप्ट कोड:

'option strict';

function largestPrimeFactor(val, divisor = 2) { 
    let square = (val) => Math.pow(val, 2);

    while ((val % divisor) != 0 && square(divisor) <= val) {
        divisor++;
    }

    return square(divisor) <= val
        ? largestPrimeFactor(val / divisor, divisor)
        : val;
}

उपयोग उदाहरण:

let result = largestPrimeFactor(600851475143);

यहाँ कोड का एक उदाहरण है :


7

@ त्रिपिटक उत्तर के समान लेकिन भिन्न भी। इस उदाहरण में सूची या शब्दकोश का उपयोग नहीं किया गया है। कोड रूबी में लिखा है

def largest_prime_factor(number)
  i = 2
  while number > 1
    if number % i == 0
      number /= i;
    else
      i += 1
    end
  end
  return i
end

largest_prime_factor(600851475143)
# => 6857

अंत में कुछ पठनीय और एक ही समय में तुरंत (js में) निष्पादन योग्य। मैं अनंत प्राइम सूची का उपयोग करने की कोशिश कर रहा था और यह 1 मिलियन पर पहले से ही धीमा था।
Ebuall

4

सभी नंबरों को primes के उत्पाद के रूप में व्यक्त किया जा सकता है, जैसे:

102 = 2 x 3 x 17
712 = 2 x 2 x 2 x 89

आप इन्हें केवल 2 से शुरू करके और केवल तब तक विभाजित करने के लिए जारी रख सकते हैं जब तक कि परिणाम आपकी संख्या का एक से अधिक न हो:

712 / 2 = 356 .. 356 / 2 = 178 .. 178 / 2 = 89 .. 89 / 89 = 1

इस पद्धति का उपयोग करने से आपको वास्तव में किसी भी प्रकार के अपराधों की गणना करने की आवश्यकता नहीं है: वे सभी अपराध होंगे, इस तथ्य के आधार पर कि आपने पहले से ही सभी पूर्ववर्ती संख्याओं के साथ जितना संभव हो उतना संख्या का कारक है।

number = 712;
currNum = number;    // the value we'll actually be working with
for (currFactor in 2 .. number) {
    while (currNum % currFactor == 0) {
        // keep on dividing by this number until we can divide no more!
        currNum = currNum / currFactor     // reduce the currNum
    }
    if (currNum == 1) return currFactor;    // once it hits 1, we're done.
}

हां, लेकिन यह बहुत ही अयोग्य है। एक बार जब आप सभी 2s को विभाजित कर लेते हैं, तो आपको वास्तव में 4, या 6, या ... से विभाजित करने की कोशिश नहीं करनी चाहिए; यह वास्तव में केवल प्राइम चेक करने या कुछ टोहर एल्गोरिथ्म का उपयोग करने की सीमा में बहुत अधिक कुशल है।
5

6
+1 ऑफ़ ऑफ़ वनोइज़, जो मुझे लगता है कि गलत है। 4 से विभाजित करने की कोशिश केवल एक बार होगी, और तुरंत विफल हो जाएगी। मुझे नहीं लगता है कि उम्मीदवारों की कुछ सूची से 4 को हटाने से भी बदतर है, और यह निश्चित रूप से पहले से सभी primes खोजने की तुलना में तेज़ है।
त्रिपिटक

2
@Beowulf। मतदान से पहले इस कोड को चलाने का प्रयास करें। यह प्रमुख कारक लौटाता है; आप अभी एल्गोरिथ्म को नहीं समझते हैं।
त्रिकोणीय

3
कोड ठीक काम करता है, लेकिन अगर आने वाली संख्या एक प्रमुख है तो धीमी है। मैं भी केवल 2 से वर्ग और वेतन वृद्धि के लिए भाग जाएगा। यह बहुत बड़ी संख्या के लिए बहुत धीमा हो सकता है, हालांकि।
blabla999

4
blabla999 बिलकुल सही है। उदाहरण 1234567898766700 = 2 * 2 * 5 * 5 * 12345678987667 है। जब हम पहुंच गए currFactor = 3513642, तो हम जानते हैं कि 12345678987667 प्रमुख है, और इसे उत्तर के रूप में वापस करना चाहिए। इसके बजाय, यह कोड केवल 12345678987667 तक गणना जारी रखेगा। यह आवश्यक से 3,513,642x धीमा है।
विल नेस

4
    //this method skips unnecessary trial divisions and makes 
    //trial division more feasible for finding large primes

    public static void main(String[] args) 
    {
        long n= 1000000000039L; //this is a large prime number 
        long i = 2L;
        int test = 0;

        while (n > 1)
        {
            while (n % i == 0)
            {
                n /= i;     
            }

            i++;

            if(i*i > n && n > 1) 
            {
                System.out.println(n); //prints n if it's prime
                test = 1;
                break;
            }
        }

        if (test == 0)  
            System.out.println(i-1); //prints n if it's the largest prime factor
    }

1
क्या आपने 1,000,000,000,039 के साथ अपने कोड की कोशिश की है? इसे पलक झपकते ही चलाना चाहिए। क्या यह?
विल नेस

2
आप इसे पहले से जान सकते थे, बिना कोशिश किए। 10 ^ 12 = (2 * 5) ^ 12 = 2 ^ 12 * 5 ^ 12। तो आपके whileपाश के iमूल्यों के माध्यम से जाना जाएगा 2,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। सभी 60 पुनरावृत्तियों। लेकिन के लिए (10 ^ 12 + 39) वहाँ (10 ^ 12 + 38) पुनरावृत्तियों, हो जाएगा i=2,3,4,5,6,...,10^12+39। भले ही 10 ^ 10 ऑप्स एक सेकंड ले, 10 ^ 12 100 सेकंड लगेंगे। लेकिन केवल 10 ^ 6 पुनरावृत्तियों की वास्तव में आवश्यकता होती है, और यदि 10 ^ 10 ऑप्स एक सेकंड लेते हैं, तो 10 ^ 6 एक सेकंड का 1 / 10,000 वां हिस्सा लेंगे।
नेस

1
क्योंकि मुझे एहसास नहीं था (10 ^ 12 + 39) एक प्रमुख संख्या थी जो अब मैं करता हूं। मुझे वही मिल रहा है जो आप कह रहे हैं।
the_prole

1
ठीक है, इसलिए आप अपना कोड बदल सकते हैं ताकि primes के लिए इतनी बड़ी मंदी न हो: यदि n = a और a <= b, तो a <= b a = n, अर्थात a <= n । और अगर हम + 1 पर पहुंच गए हैं, तो n निश्चित रूप से एक प्रमुख है। (यदि आप इसे शामिल करने के लिए अपना उत्तर संपादित करते हैं तो मुझे पिंग करें)।
नेस

1
क्या जब होता है long n = 2*1000000000039L? क्या यह उतनी ही तेजी से काम करता है जितना इसे करना चाहिए? (यह भी, क्या आप एक return;कथन का उपयोग करके अपने कोड को सरल बना सकते हैं ?)। (यदि आप चाहते हैं कि मैं आपको कुहनी मारना बंद कर दूं, तो बस इतना ही कहना;)
विल नेस

4

सबसे सरल समाधान पारस्परिक रूप से पुनरावर्ती कार्यों की एक जोड़ी है ।

पहला फ़ंक्शन सभी अभाज्य संख्याएँ उत्पन्न करता है:

  1. 1 से अधिक सभी प्राकृतिक संख्याओं की सूची के साथ शुरू करें।
  2. उन सभी नंबरों को हटा दें जो प्राइम नहीं हैं। वह है, संख्याएँ जिनका कोई प्रधान कारक नहीं है (स्वयं के अलावा)। निचे देखो।

दूसरा फ़ंक्शन nबढ़ते हुए क्रम में किसी दिए गए नंबर के प्रमुख कारकों को लौटाता है ।

  1. सभी अपराधों की सूची लें (ऊपर देखें)।
  2. उन सभी नंबरों को हटा दें, जिनके कारक नहीं हैं n

सबसे बड़ा मुख्य कारक nदूसरे फ़ंक्शन द्वारा दिया गया अंतिम नंबर है।

इस एल्गोरिथ्म में एक आलसी सूची या एक भाषा (या डेटा संरचना) की आवश्यकता होती है जिसमें कॉल-बाय- नीड शब्दार्थ है।

स्पष्टीकरण के लिए, हास्केल में उपरोक्त में से एक (अक्षम) कार्यान्वयन है:

import Control.Monad

-- All the primes
primes = 2 : filter (ap (<=) (head . primeFactors)) [3,5..]

-- Gives the prime factors of its argument
primeFactors = factor primes
  where factor [] n = []
        factor xs@(p:ps) n =
          if p*p > n then [n]
          else let (d,r) = divMod n p in
            if r == 0 then p : factor xs d
            else factor ps n

-- Gives the largest prime factor of its argument
largestFactor = last . primeFactors

इस तेजी से बनाना सिर्फ यह पता लगाने के बारे में अधिक चतुर होने की बात है कि कौन से नंबर प्रमुख हैं और / या कारक हैं n, लेकिन एल्गोरिथ्म समान रहता है।


2
n = abs(number);
result = 1;
if (n mod 2 == 0) {
  result = 2;
  while (n mod 2 = 0) n /= 2;
}
for(i=3; i<sqrt(n); i+=2) {
  if (n mod i == 0) {
    result = i;
    while (n mod i = 0)  n /= i;
  }
}
return max(n,result)

कुछ मॉडुलो परीक्षण हैं जो अतिरेक हैं, क्योंकि n को कभी भी 6 से विभाजित नहीं किया जा सकता है यदि सभी कारकों 2 और 3 को हटा दिया गया हो। आप केवल i के लिए primes की अनुमति दे सकते हैं, जो यहां कई अन्य उत्तरों में दिखाया गया है।

आप वास्तव में यहाँ Eratosthenes की छलनी को देख सकते हैं:

  • पहले पूर्णांक (n) तक पूर्णांकों की सूची बनाएं।
  • लूप फॉर फॉर मार्क में, नए sqrt (n) तक के सभी गुणकों को प्रधान नहीं, और इसके बजाय थोड़ी देर के लूप का उपयोग करें।
  • सूची में अगले मुख्य नंबर पर सेट करें

इस प्रश्न को भी देखें ।


2

मुझे पता है कि यह एक तेज़ समाधान नहीं है। धीमे समाधान को समझने के लिए उम्मीद के मुताबिक पोस्ट करना।

 public static long largestPrimeFactor(long n) {

        // largest composite factor must be smaller than sqrt
        long sqrt = (long)Math.ceil(Math.sqrt((double)n));

        long largest = -1;

        for(long i = 2; i <= sqrt; i++) {
            if(n % i == 0) {
                long test = largestPrimeFactor(n/i);
                if(test > largest) {
                    largest = test;
                }
            }
        }

        if(largest != -1) {
            return largest;
        }

        // number is prime
        return n;
    } 

1

संख्या से सभी प्रमुख कारकों को हटाकर पायथन इटरेटिव दृष्टिकोण

def primef(n):
    if n <= 3:
        return n
    if n % 2 == 0:
        return primef(n/2)
    elif n % 3 ==0:
        return primef(n/3)
    else:
        for i in range(5, int((n)**0.5) + 1, 6):
            #print i
            if n % i == 0:
                return primef(n/i)
            if n % (i + 2) == 0:
                return primef(n/(i+2))
    return n

1

मैं एल्गोरिथ्म का उपयोग कर रहा हूं जो वर्तमान प्रधान कारक द्वारा संख्या को विभाजित करना जारी रखता है।

अजगर 3 में मेरा समाधान:

def PrimeFactor(n):
    m = n
    while n%2==0:
        n = n//2
    if n == 1:         # check if only 2 is largest Prime Factor 
        return 2
    i = 3
    sqrt = int(m**(0.5))  # loop till square root of number
    last = 0              # to store last prime Factor i.e. Largest Prime Factor
    while i <= sqrt :
        while n%i == 0:
            n = n//i       # reduce the number by dividing it by it's Prime Factor
            last = i
        i+=2
    if n> last:            # the remaining number(n) is also Factor of number 
        return n
    else:
        return last
print(PrimeFactor(int(input()))) 

इनपुट: 10 आउटपुट:5

इनपुट: 600851475143 आउटपुट:6857


0

यहाँ c # में मेरा प्रयास है। अंतिम प्रिंट आउट संख्या का सबसे बड़ा प्रमुख कारक है। मैंने जाँच की और यह काम करता है।

namespace Problem_Prime
{
  class Program
  {
    static void Main(string[] args)
    {
      /*
       The prime factors of 13195 are 5, 7, 13 and 29.

      What is the largest prime factor of the number 600851475143 ?
       */
      long x = 600851475143;
      long y = 2;
      while (y < x)
      {
        if (x % y == 0)
        {
          // y is a factor of x, but is it prime
          if (IsPrime(y))
          {
            Console.WriteLine(y);
          }
          x /= y;
        }

        y++;

      }
      Console.WriteLine(y);
      Console.ReadLine();
    }
    static bool IsPrime(long number)
    {
      //check for evenness
      if (number % 2 == 0)
      {
        if (number == 2)
        {
          return true;
        }
        return false;
      }
      //don't need to check past the square root
      long max = (long)Math.Sqrt(number);
      for (int i = 3; i <= max; i += 2)
      {
        if ((number % i) == 0)
        {
          return false;
        }
      }
      return true;
    }

  }
}

0
#python implementation
import math
n = 600851475143
i = 2
factors=set([])
while i<math.sqrt(n):
   while n%i==0:
       n=n/i
       factors.add(i)
   i+=1
factors.add(n)
largest=max(factors)
print factors
print largest

1
25 का सबसे बड़ा मुख्य कारक 25 है?
विल नेस

0

C ++ में पुनरावर्तन का उपयोग करके किसी संख्या के सबसे बड़े कारक की गणना करता है। कोड का काम नीचे बताया गया है:

int getLargestPrime(int number) {
    int factor = number; // assumes that the largest prime factor is the number itself
    for (int i = 2; (i*i) <= number; i++) { // iterates to the square root of the number till it finds the first(smallest) factor
        if (number % i == 0) { // checks if the current number(i) is a factor
            factor = max(i, number / i); // stores the larger number among the factors
            break; // breaks the loop on when a factor is found
        }
    }
    if (factor == number) // base case of recursion
        return number;
    return getLargestPrime(factor); // recursively calls itself
}

0

यहाँ मेरा दृष्टिकोण सबसे बड़े अभाज्य कारक की शीघ्र गणना करना है। यह इस तथ्य पर आधारित है कि संशोधित xमें गैर-प्रमुख कारक शामिल नहीं हैं। इसे प्राप्त करने के लिए, हम xएक कारक मिलते ही विभाजित करते हैं। फिर, केवल एक चीज बची है जो सबसे बड़ा कारक है। यह पहले से ही प्रधान होगा।

कोड (हास्केल):

f max' x i | i > x = max'
           | x `rem` i == 0 = f i (x `div` i) i  -- Divide x by its factor
           | otherwise = f max' x (i + 1)  -- Check for the next possible factor

g x = f 2 x 2

लेकिन यह सब भी संख्या के साथ विभाजित करने की कोशिश नहीं करेंगे?
जानूस ट्रॉल्सन

0

निम्नलिखित C ++ एल्गोरिथ्म सबसे अच्छा एक नहीं है, लेकिन यह एक बिलियन और इसके बहुत तेज के तहत संख्याओं के लिए काम करता है

#include <iostream>
using namespace std;

// ------ is_prime ------
// Determines if the integer accepted is prime or not
bool is_prime(int n){
    int i,count=0;
    if(n==1 || n==2)
      return true;
    if(n%2==0)
      return false;
    for(i=1;i<=n;i++){
    if(n%i==0)
        count++;
    }
    if(count==2)
      return true;
    else
      return false;
 }
 // ------ nextPrime -------
 // Finds and returns the next prime number
 int nextPrime(int prime){
     bool a = false;
     while (a == false){
         prime++;
         if (is_prime(prime))
            a = true;
     }
  return prime;
 }
 // ----- M A I N ------
 int main(){

      int value = 13195;
      int prime = 2;
      bool done = false;

      while (done == false){
          if (value%prime == 0){
             value = value/prime;
             if (is_prime(value)){
                 done = true;
             }
          } else {
             prime = nextPrime(prime);
          }
      }
        cout << "Largest prime factor: " << value << endl;
 }

0

"जेम्स वैंग" द्वारा वेब पर यह समाधान मिला

public static int getLargestPrime( int number) {

    if (number <= 1) return -1;

    for (int i = number - 1; i > 1; i--) {
        if (number % i == 0) {
            number = i;
        }
    }
    return number;
}

0

चलनी का उपयोग करने वाला मुख्य कारक:

#include <bits/stdc++.h>
using namespace std;
#define N 10001  
typedef long long ll;
bool visit[N];
vector<int> prime;

void sieve()
{
            memset( visit , 0 , sizeof(visit));
            for( int i=2;i<N;i++ )
            {
                if( visit[i] == 0)
                {
                    prime.push_back(i);
                    for( int j=i*2; j<N; j=j+i )
                    {
                        visit[j] = 1;
                    }
                }
            }   
}
void sol(long long n, vector<int>&prime)
{
            ll ans = n;
            for(int i=0; i<prime.size() || prime[i]>n; i++)
            {
                while(n%prime[i]==0)
                {
                    n=n/prime[i];
                    ans = prime[i];
                }
            }
            ans = max(ans, n);
            cout<<ans<<endl;
}
int main() 
{
           ll tc, n;
           sieve();

           cin>>n;
           sol(n, prime);

           return 0;
}

-1

यह मुझे लगता है कि दिए गए एल्गोरिथम का चरण # 2 ऐसा नहीं है जो एक कुशल तरीका है। आपको कोई उचित उम्मीद नहीं है कि यह प्रमुख है।

इसके अलावा, इरेटोस्थनीज की छलनी का सुझाव देने वाला पिछला उत्तर सरासर गलत है। मैंने सिर्फ 123456789 फैक्टर पर दो कार्यक्रम लिखे। एक छलनी पर आधारित था, एक निम्नलिखित पर आधारित था:

1)  Test = 2 
2)  Current = Number to test 
3)  If Current Mod Test = 0 then  
3a)     Current = Current Div Test 
3b)     Largest = Test
3c)     Goto 3. 
4)  Inc(Test) 
5)  If Current < Test goto 4
6)  Return Largest

यह संस्करण चलनी से 90x तेज था।

बात यह है कि आधुनिक प्रोसेसर पर ऑपरेशन का प्रकार ऑपरेशन की संख्या से बहुत कम मायने रखता है, यह उल्लेख नहीं करने के लिए कि ऊपर एल्गोरिथ्म कैश में चल सकता है, चलनी नहीं हो सकता। छलनी सभी संयुक्त संख्याओं को छीनते हुए बहुत सारे ऑपरेशन का उपयोग करती है।

ध्यान दें, यह भी कि मेरे विभाजन के कारकों की पहचान के रूप में वे उस स्थान को कम कर देते हैं जिसे परीक्षण किया जाना चाहिए।


यही मैंने कहा, लेकिन मतदान हो गया :( मुझे लगता है कि समस्या यह है कि यदि संख्या में वास्तव में बड़ा कारक है (जैसे कि स्वयं), तो इस विधि को उस संख्या तक सभी तरह से लूप करना होगा। बहुत सारे मामलों में। हालांकि, यह विधि काफी कुशल है।
5

आपके माध्यम से वापस पढ़ना यह वही है लेकिन आपका पहला भाग भ्रामक है।
लोरेन Pechtel

कोशिश करें कि इस नंबर पर 143816789988504044536402352738195137863656439, मुझे बताएं कि यह कितना कारगर है ...
माइकलिस

-1

पहले प्रमुख संख्याएँ संग्रहीत करने वाली सूची की गणना करें, जैसे 2 3 5 7 11 13 ...

हर बार जब आप किसी संख्या को प्रधान करते हैं, तो ट्राइपटिक द्वारा कार्यान्वयन का उपयोग करते हैं लेकिन प्राकृतिक पूर्णांकों के बजाय अभाज्य संख्याओं की इस सूची को पुनरावृत्त करते हैं।


-1

जावा के साथ:

के लिए intमान:

public static int[] primeFactors(int value) {
    int[] a = new int[31];
    int i = 0, j;
    int num = value;
    while (num % 2 == 0) {
        a[i++] = 2;
        num /= 2;
    }
    j = 3;
    while (j <= Math.sqrt(num) + 1) {
        if (num % j == 0) {
            a[i++] = j;
            num /= j;
        } else {
            j += 2;
        }
    }
    if (num > 1) {
        a[i++] = num;
    }
    int[] b = Arrays.copyOf(a, i);
    return b;
}

के लिए longमान:

static long[] getFactors(long value) {
    long[] a = new long[63];
    int i = 0;
    long num = value;
    while (num % 2 == 0) {
        a[i++] = 2;
        num /= 2;
    }
    long j = 3;
    while (j <= Math.sqrt(num) + 1) {
        if (num % j == 0) {
            a[i++] = j;
            num /= j;
        } else {
            j += 2;
        }
    }
    if (num > 1) {
        a[i++] = num;
    }
    long[] b = Arrays.copyOf(a, i);
    return b;
}

-2

यह शायद हमेशा तेज़ नहीं होता है, लेकिन इसके बारे में अधिक आशावादी होता है कि आप एक बड़ा प्राइम डिविज़र पाते हैं:

  1. N आपका नंबर है
  2. अगर यह प्रमुख है return(N)
  3. तक की गणना करें Sqrt(N)
  4. अवरोही क्रम में primes से गुजरें (सबसे पहले)
    • अगर है N is divisible by PrimeतोReturn(Prime)

संपादित करें: चरण 3 में आप एटकॉस्टेनेस की छलनी या एटकिन्स की छलनी का उपयोग कर सकते हैं या आपको जो भी पसंद हो, लेकिन स्वयं चलनी आपको सबसे बड़ा प्रमुख कारक नहीं मिलेगा। (यही कारण है कि मैं आधिकारिक जवाब के रूप में SQLMenace का पद नहीं चुनूंगा ...)


1
क्या आपको यह निर्धारित करने के लिए ट्रायल फैक्टरिंग करने की आवश्यकता नहीं है कि क्या यह एक प्रमुख संख्या (चरण 2) है? इसके अलावा, 15. का सबसे बड़ा मुख्य कारक खोजने पर विचार करें। sqrt (15) तक के अपराध 2 और 3 हैं; लेकिन सबसे बड़ा कारक 5 है, है ना? इसी तरह 20 के साथ।
जोनाथन लेफ़लर

-3

मुझे लगता है कि सभी संभव छोटे प्राइमरों को स्टोर करना अच्छा होगा, फिर सबसे बड़ा डिवीज़न खोजने के लिए उनके माध्यम से n और सिर्फ पुनरावृति करें। आप प्राइम- numbers.org से प्राइम प्राप्त कर सकते हैं

निश्चित रूप से मैं मानता हूं कि आपका नंबर बहुत बड़ा नहीं है :)


-3

सबसे तेज नहीं है, लेकिन यह काम करता है!

    static bool IsPrime(long num)
    {
        long checkUpTo = (long)Math.Ceiling(Math.Sqrt(num));
        for (long i = 2; i <= checkUpTo; i++)
        {
            if (num % i == 0)
                return false;
        }
        return true;
    }

यह सवाल का जवाब नहीं है। ;-) सवाल सबसे बड़ा प्रमुख कारक खोजने के बारे में था, न कि मौलिकता की जाँच के लिए।
हंस-पीटर स्टॉर

यह आपके लूप को इनिशियलाइज़ करने के लिए बहुत अधिक कुशल है (लंबे i = 3; मैं <चेकअप; मैं + = 2)
cjk

-3

यहाँ एक ही फंक्शन @ Triptych जनरेटर के रूप में प्रदान किया गया है, जिसे थोड़ा सरल भी किया गया है।

def primes(n):
    d = 2
    while (n > 1):
        while (n%d==0):
            yield d
            n /= d
        d += 1

अधिकतम प्राइम का उपयोग करके पाया जा सकता है:

n= 373764623
max(primes(n))

और उपयोग किए जाने वाले कारकों की एक सूची:

list(primes(n))

-6
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include <time.h>

factor(long int n)
{
long int i,j;
while(n>=4)
 {
if(n%2==0) {  n=n/2;   i=2;   }

 else
 { i=3;
j=0;
  while(j==0)
  {
   if(n%i==0)
   {j=1;
   n=n/i;
   }
   i=i+2;
  }
 i-=2;
 }
 }
return i;
 }

 void main()
 { 
  clock_t start = clock();
  long int n,sp;
  clrscr();
  printf("enter value of n");
  scanf("%ld",&n);
  sp=factor(n);
  printf("largest prime factor is %ld",sp);

  printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
  getch();
 }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.