2013-03-12 9 views
5

पायथन में, आप कैसे जांच सकते हैं कि संख्या एन बेस बी की सटीक शक्ति है या नहीं?कैसे जांचें कि कोई संख्या बेस बी की शक्ति है या नहीं?

नोट: इसे पैरामीटर के रूप में दिए गए किसी भी आधार पर सामान्यीकृत करने की आवश्यकता है।

यहाँ मैं क्या मिला है:

n मान लें और आधार पूर्णांकों> 0.

import math 
def is_power(n,base): 
    return math.log(n,base) == base**n 
+3

मदद करता है कि आप जांच नहीं कर रहे हैं कि math.log (n, base) * कोई * पूर्णांक है या नहीं? –

+3

'math.log (n, base)' बराबर बराबर 'आधार ** एन' क्यों होगा? 128 2 की शक्ति है, लेकिन '2 ** 128' निश्चित रूप से' 7' नहीं है। – chrisaycock

उत्तर

9

सबसे पहले, यह सोचते हैं आप एक विशिष्ट लघुगणक ऑपरेटर है (कई भाषाओं लघुगणक 10 या आधार के आधार के लिए प्रदान कर रहे हैं e केवल), logab को logxb/logxa के रूप में गणना की जा सकती है (जहां x स्पष्ट रूप से आधार है जो आपकी भाषा प्रदान करता है)।

पायथन एक बेहतर हो जाता है क्योंकि यह ऊपर की मुश्किल समानता के बिना मनमानी आधार के लिए लॉगरिदम का काम कर सकता है।

तो एक तरफ या दूसरा, आपके पास एक विशिष्ट आधार पर लॉगरिदम प्राप्त करने का एक तरीका है। वहां से, यदि का आधार a में एक पूर्णांक (नोट 1) है, तो ba की शक्ति है।

तो मैं जोड़ा किनारे मामलों की पहचान के साथ निम्न कोड के साथ शुरू करना चाहते हैं, अब:

# Don't even think about using this for negative powers :-) 

def isPower (num, base): 
    if base == 1 and num != 1: return False 
    if base == 1 and num == 1: return True 
    if base == 0 and num != 1: return False 
    power = int (math.log (num, base) + 0.5) 
    return base ** power == num 

उदाहरण के लिए देखें निम्नलिखित पूरा कार्यक्रम जो कार्रवाई में यह पता चलता है:

import math 

def isPower (num, base): 
    if base == 1 and num != 1: return False 
    if base == 1 and num == 1: return True 
    if base == 0 and num != 1: return False 
    power = int (math.log (num, base) + 0.5) 
    return base ** power == num 

print isPower (127,2)  # false 
print isPower (128,2)  # true 
print isPower (129,2)  # false 
print 

print isPower (26,3)  # false 
print isPower (27,3)  # true 
print isPower (28,3)  # false 
print isPower (3**10,3)  # true 
print isPower (3**129,3) # true 
print 

print isPower (5,5)   # true 
print isPower (1,1)   # true 
print isPower (10,1)  # false 

यदि आप ऐसे हैं जो फ़्लोटिंग पॉइंट ऑपरेशंस के बारे में चिंतित हैं, तो आप बार-बार गुणा के साथ कर सकते हैं लेकिन आपको प्रदर्शन का परीक्षण करना चाहिए ऐसे समाधान का एनसीई क्योंकि यह हार्डवेयर में हार्डवेयर की तुलना में काफी धीमी होने की संभावना है। isPower(128,2) जैसी चीजों के लिए इससे कोई फर्क नहीं पड़ता है, लेकिन यह isPower(verybignum,2) के लिए चिंता का विषय बन सकता है।

ऊपर कोड की एक गैर फ्लोटिंग बिंदु संस्करण के लिए:

def isPower (num, base): 
    if base == 1 and num != 1: return False 
    if base == 1 and num == 1: return True 
    if base == 0 and num != 1: return False 
    testnum = base 
    while testnum < num: 
     testnum = testnum * base 
    return testnum == num 

लेकिन यकीन है कि यह आप किसी भी प्रदर्शन के झटके नहीं मिलता है सुनिश्चित करने के लिए अपने सबसे बड़ी संख्या है और छोटी से छोटी आधार के खिलाफ परीक्षण किया है बनाते हैं।


(नोट 1) संभावना को ध्यान में यहाँ रखें चल बिन्दु अस्पष्टता यह बिल्कुल कोई पूर्णांक नहीं है मतलब हो सकता है कि। आपको "पर्याप्त बंद" तुलना का उपयोग करना पड़ सकता है।

+1

1) 'math.exp' केवल 1 तर्क लेता है। यदि आप इसे ठीक करते हैं, तो 2) आपको 'isPower (3 ** 10, 3) 'के लिए गलत जवाब मिलेगा। –

+0

'आईएसपावर (1, 1) ' – wim

+0

@ रॉब, जैसे सीमा मामलों के लिए विफलता,' एक्सपी 'गलत कार्य था, इसे' पाउ 'में बदल दिया गया है। – paxdiablo

-1
>>> def isPower(n, b): 
... return b**int(math.log(n, b)+.5)==n 
... 
>>> isPower(128, 2) 
True 
>>> isPower(129, 2) 
False 
>>> isPower(3**10, 3) 
True 
>>> isPower(3**129, 3) 
True 
>>> isPower(10**500, 10) 
True 
>>> isPower(10**(10**6), 10) 
True 


संपादित: इस कोड 1,1 के लिए असफल करता है:

>>> isPower(1,1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in isPower 
ZeroDivisionError: float division by zero 

मैं अगर वह तुच्छ सुधार लागू करने या उसकी आवश्यकताओं को फिर से लिखने के लिए करना चाहता तय करने के लिए ओ पी करने के लिए इसे छोड़ देंगे।

+0

आधार 1 – wim

+0

सच के लिए विफल रहता है। लेकिन मैं इसे पाठक को छोड़ दूंगा। –

3

एक बहुत ही सरल समाधान इस तरह जा सकते हैं:

def ispower(n, base): 

    if n == base: 
     return True 

    if base == 1: 
     return False 

    temp = base 

    while (temp <= n): 
     if temp == n: 
      return True 
     temp *= base 

    return False 

परिणाम:

>>> ispower(32, 2) 
True 
>>> ispower(81, 3) 
True 
>>> ispower(625, 5) 
True 
>>> ispower(50, 5) 
False 
>>> ispower(32, 4) 
False 
>>> ispower(2,1) 
False 
>>> ispower(1,1) 
True 
+0

+1 बहुत अच्छा है। आप असीमित पाश केस को 'सशक्तिकरण (2, 1)' जैसे कुछ के साथ ठीक करना चाहते हैं। – wim

+0

@ धन्यवाद, तय करें। – Akavall

+0

आपने अनंत लूप को ठीक किया है, लेकिन आपने एक बग लिखा है। 'सशक्तिकरण (2, 1) 'गलत होना चाहिए। – wim

0

मैं लॉग सामान है, जो चल बिन्दु जटिलताओं के लिए विषय हो सकता है भूल जाते हैं, और सिर्फ iteratively ऐसा करने :

def is_power(n, base): 
    if base == 1: 
     # note: the question stated "Assume n and base are integers > 0" 
     return n == 1 
    while n % base == 0: 
     n //= base 
     if n == 1: 
      return True 
    return False 

आप कर सकते थे शायद एक लाइनर यह reduce औरके साथ, लेकिन ऐसा करने के लिए यह पाइथोनिक नहीं होगा।

+0

'1' से शुरू करने के लिए और अधिक सक्षम नहीं है और' आधार '('आधार' की शक्तियों) से' n' की ओर बढ़ना है? –

+0

हां, निश्चित रूप से, लेकिन ऐसा करने के लिए पहले से ही एक और जवाब है :) – wim

0

>>>(math.log(int(num),int(base))).is_integer()

यह एक बूलियन मान सही या गलत वापस आ जाएगी। यह ठीक काम करना चाहिए। उम्मीद है कि यह

+0

नहीं, '(math.log (4 9 13, 17)) का प्रयास करें। Is_integer() 'उदाहरण के लिए। –

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