2008-12-05 18 views
60

संभव डुप्लिकेट:
Fastest way to determine if an integer's square root is an integerयह निर्धारित करने के लिए एक अच्छा एल्गोरिदम क्या है कि कोई इनपुट एक पूर्ण वर्ग है या नहीं?

क्या होगा यदि एक नंबर एक perfect square है देखने का कोई तरीका है?

bool IsPerfectSquare(long input) 
{ 
    // TODO 
} 

मैं सी # का उपयोग कर रहा है, लेकिन इस नास्तिक भाषा है।

स्पष्टता और सादगी के लिए बोनस अंक (यह कोड-गोल्फ नहीं है)।


संपादित करें: यह और अधिक जटिल हो गया मेरी अपेक्षा से! यह डबल परिशुद्धता वाले समस्याओं को स्वयं को दो तरीकों से प्रकट करता है। सबसे पहले, Math.Sqrt एक डबल लेता है जो ठीक से लंबे समय तक नहीं रख सकता (धन्यवाद जॉन)।

दूसरा, एक डबल की सटीकता छोटे मान (.000 ... 00001) खो जाएगी जब आपके पास एक विशाल, पूर्ण वर्ग के पास होगा। उदाहरण के लिए, मेरा कार्यान्वयन Math.Pow (10,18) +1 (मेरा सत्य सत्य) के लिए इस परीक्षण में विफल रहा।

+0

आप पूर्णांक वर्ग रूट के लिए उपयोग की जाने वाली 'lsqrt' विधि के लिए भी Google पर जा सकते हैं। – leppie

+0

माइकल, बिल द लिज़र ने एक अच्छा मुद्दा बना दिया कि यह एक समान प्रश्न है, सटीक डुप्लिकेट नहीं। मुझे नहीं लगता कि सवाल बंद होना चाहिए। सही वर्ग की समस्या के अलावा व्यावहारिक शर्तों में यह अधिक जटिल है और ऐसा लगता है कि यहां कुछ योगदान दिए गए हैं। –

+0

आपके द्वारा चुने गए समाधान के लिए, नकारात्मकता के लिए त्वरित जांच पूर्ववत करना न भूलें। – angus

उत्तर

98
bool IsPerfectSquare(long input) 
{ 
    long closestRoot = (long) Math.Sqrt(input); 
    return input == closestRoot * closestRoot; 
} 

यह सिर्फ जाँच की समस्याओं में से कुछ से दूर होने सकते हैं, लेकिन संभवतः सभी नहीं "वर्गमूल एक पूर्णांक है"।

bool IsPerfectSquare(long input) 
{ 
    double root = Math.Sqrt(input); 

    long rootBits = BitConverter.DoubleToInt64Bits(root); 
    long lowerBound = (long) BitConverter.Int64BitsToDouble(rootBits-1); 
    long upperBound = (long) BitConverter.Int64BitsToDouble(rootBits+1); 

    for (long candidate = lowerBound; candidate <= upperBound; candidate++) 
    { 
     if (candidate * candidate == input) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

को भावुक, और वास्तव में बड़े मूल्यों के अलावा और कुछ के लिए अनावश्यक है, लेकिन मुझे लगता है कि यह चाहिए काम ...

+0

ऐसा लगता है कि आप मुझसे अधिक तेज़ थे ;-) ओह - आपका समाधान भी बेहतर है, क्योंकि 'closestRoot' एक बहुत मोर सटीक नाम है। – Treb

+21

अधिक बुलेटप्रूफ समाधान में इसे ठीक करने से पहले * प्राप्त किए गए अपवॉट्स की संख्या से प्यार करें;) –

+168

दोस्त, आप जोन स्कीट हैं। – Epaga

10
bool IsPerfectSquare(long input) 
{ 
    long SquareRoot = (long) Math.Sqrt(input); 
    return ((SquareRoot * SquareRoot) == input); 
} 
9

में: आप संभवतः एक छोटा सा funkier प्राप्त करने की आवश्यकता सामान्य लिस्प, मैं निम्नलिखित का उपयोग करता हूं:

(defun perfect-square-p (n) 
    (= (expt (isqrt n) 2) 
    n)) 
+0

हे। Http://stackoverflow.com/a/343862/31615 पर देखकर, मुझे यह जोड़ना चाहिए कि सामान्य लिस्प में "पूर्ण" संख्या का ढेर है, इसलिए यह _just works_ किसी भी गैर-ऋणात्मक पूर्ण संख्या के लिए कार्य करता है (निश्चित रूप से कार्यशील स्मृति द्वारा सीमित) । – Svante

+0

एसबीसीएल पर, 'वर्ग'' expt' होना चाहिए: '(सही-वर्ग-पी (एन) को परिभाषित करें (= (expt (isqrt n) 2) n))'। – Ben

+0

@ बेनसिमा: वास्तव में, चूंकि मानक में 'वर्ग' परिभाषित नहीं किया गया है, इसलिए आपको इसे किसी भी कार्यान्वयन में परिभाषित करने (या प्रतिस्थापित) करने की आवश्यकता है। इस तरह की निर्भरता न होने के लिए मैं जवाब संपादित करता हूं। – Svante

संबंधित मुद्दे

 संबंधित मुद्दे