2012-06-08 14 views
19

मैं एक मिश्रित संख्या वर्ग लिख रहा हूं और एक त्वरित और आसान 'सबसे बड़ा आम divisor' फ़ंक्शन की आवश्यकता है। क्या कोई मुझे कोड या कोड के लिंक दे सकता है?सी ++ संस cmath लाइब्रेरी में जीसीडी फ़ंक्शन

+0

Btw: यह सबसे बड़ा आम भाजक 'कहा जाता है। – bjoernz

+0

यहां मज़ेदार लोगों का एक गुच्छा है: http://codegolf.stackexchange.com/questions/35587/ – technosaurus

उत्तर

30

मुझे बंद करने के लिए वोट देने का लुत्फ उठाना है - ऐसा लगता है कि एक कार्यान्वयन मुश्किल होगा, लेकिन जो निश्चित रूप से जानता है।

unsigned GCD(unsigned u, unsigned v) { 
    while (v != 0) { 
     unsigned r = u % v; 
     u = v; 
     v = r; 
    } 
    return u; 
} 
+1

धन्यवाद। और मैं एक अच्छा 20 मिनट के लिए googled और कोई स्पष्ट परिणाम नहीं मिला। –

+0

क्यों हस्ताक्षरित का उपयोग करें? –

+0

@EnjoysMath: अधिकतर क्योंकि कम से कम आप जीसीडी का उपयोग करना चाहते हैं, तो आप हस्ताक्षरित संख्याओं से निपट रहे हैं। –

16

एक त्वरित पुनरावर्ती संस्करण:

unsigned int gcd (unsigned int n1, unsigned int n2) { 
    return (n2 == 0) ? n1 : gcd (n2, n1 % n2); 
} 

या समकक्ष पुनरावृत्ति संस्करण यदि आप हिंसक प्रत्यावर्तन करने का विरोध कर रहे हैं (क):

unsigned int gcd (unsigned int n1, unsigned int n2) { 
    unsigned int tmp; 
    while (n2 != 0) { 
     tmp = n1; 
     n1 = n2; 
     n2 = tmp % n2; 
    } 
    return n1; 
} 

अपनी खुद में बस स्थानापन्न डेटा प्रकार, शून्य तुलना, असाइनमेंट और मॉड्यूलस विधि (यदि आप उदाहरण के लिए bignum कक्षा जैसे कुछ गैर-मूल प्रकार का उपयोग कर रहे हैं)।

इस समारोह वास्तव में स्क्रीन आकार के लिए अभिन्न पहलू अनुपात बाहर काम करने के लिए एक earlier answer of mine से आया है लेकिन मूल स्रोत इयूक्लिडियन एल्गोरिथ्म मैं एक लंबे समय पहले सीखा है, विस्तृत here on Wikipedia था अगर आप इसके पीछे गणित जानना चाहते हैं।


(क) कुछ पुनरावर्ती समाधान के साथ समस्या यह है कि वे इस तरह के बहुत बुरी तरह से बाहर सोचा (छद्म साथ के रूप में जवाब दृष्टिकोण तो धीरे धीरे आपको ढेर स्थान शेष नहीं करते हैं इससे पहले कि आप वहां पहुंचें, है कोड):

def sum (a:unsigned, b:unsigned): 
    if b == 0: return a 
    return sum (a + 1, b - 1) 

आपको लगता है कि बहुत sum (1, 1000000000) की तरह कुछ पर महंगा लगता है के रूप में आप (करने की कोशिश) एक अरब का उपयोग या तो फ्रेम ढेर होगा। रिकर्सन के लिए आदर्श उपयोग केस बाइनरी खोज की तरह कुछ है जहां आप प्रत्येक पुनरावृत्ति के लिए आधे से समाधान स्थान को कम करते हैं। सबसे बड़ा आम विभाजक भी एक है जहां समाधान स्थान तेजी से कम हो जाता है, इसलिए भारी ढेर के उपयोग के बारे में डर वहां बेकार हैं।

+0

+1 आप 'int' को प्रतिस्थापित करने के लिए 'टेम्पलेट <वर्ग इंटीग्रल>' भी जोड़ सकते हैं, फ़ंक्शन से पहले 'constexpr' कीवर्ड जोड़ें और आपके पास एक अच्छा संकलन-समय/रनटाइम जेनेरिक फ़ंक्शन है। – authchir

+0

आपकी दूसरी विधि में संभावित टाइपो। क्या यह वापस एन 1' होना चाहिए? एन 2 परिभाषा के अनुसार हमेशा उस बिंदु पर शून्य हो जाएगा। –

+0

अच्छी पकड़, @ जिम, तय है कि ऊपर। – paxdiablo

4

Euclidean एल्गोरिथ्म सी

int gcd(int a, int b) { 
    while (b != 0) { 
    int t = b; 
    b = a % b; 
    a = t; 
    } 
    return a; 
} 
47

libstdC++ एल्गोरिथ्म पुस्तकालय एक छिपा gcd समारोह (मैं जी का उपयोग कर रहा ++ 4.6.3) है में लिखने के लिए काफी आसान है।

#include <iostream> 
#include <algorithm> 

int main() 
{ 
    cout << std::__gcd(100,24); 
    return 0; 
} 

आपका स्वागत है :)

अद्यतन: जैसा कि @ chema989, यह ध्यान दिया सी ++ 17 वहाँ std::gcd() समारोह <numeric> हैडर के साथ उपलब्ध है में।

+18

आपको गैर-दस्तावेज सुविधाओं पर भरोसा नहीं करना चाहिए क्योंकि वे लाइब्रेरी रिलीज़ के बीच बदल सकते हैं। – vmrob

+0

क्या यह एमएसवीसी के लिए उपलब्ध है? –

+1

@vmrob: सहमत। आप हमेशा एसटीएल से कार्यान्वयन की प्रतिलिपि बना सकते हैं। एमबीटी 9 25: हो गया। –

-2

मेरे दो सेंट; टेम्प्लेट की इयूक्लिडियन एल्गोरिथ्म अहस्ताक्षरित पूर्णांक प्रकार के लिए XOR swap का उपयोग कर:

template <class Unsigned> 
Unsigned gcd(Unsigned a, Unsigned b) 
{ 

    static_assert(
     std::numeric_limits<Unsigned>::is_integer && 
     !std::numeric_limits<Unsigned>::is_signed, "Unsigned required."); 

    while (b) 
    { 
     b ^= a; 
     a ^= b; 
     b = (b^a) % a; 
    } 
    return a; 
} 
+0

यह जानना अच्छा होगा कि यह क्यों हो जाता है। – Sheljohn

+2

क्योंकि आप इसके लिए कंपाइलर का काम करने की कोशिश कर रहे हैं। मत करो। यह एक्सओआर स्वैप के बारे में जानता है। आप जो भी कर सकते हैं उसके साथ हस्तक्षेप करने की अधिक संभावना है (उदा। कुछ हद तक लूप को अनलॉक करना)। – einpoklum

+0

यदि आप इसे फ्लोट करने की कोशिश करते हैं तो यह टूट जाएगा। यदि आपने एक्सोर-स्वैप के बजाय नियमित स्वैप का उपयोग किया है, तो ऐसा नहीं होगा। इसके अलावा @ एनोपोकलम ने कहा, अन्य अनुकूलन भी लागू नहीं होंगे। सीपीयू में एक विशेष स्वैप निर्देश हो सकता है जो xors के कारण उपयोग नहीं किया जाता है। – Pharap

5

std::gcd के लिए सी ++ 17 आप उपयोग कर सकते हैं हैडर <numeric> में परिभाषित:

auto res = std::gcd(10, 20); 
संबंधित मुद्दे