2011-01-19 10 views
6

Attualmente sto usando singpath.com di praticare il mio pitone, ma affronto un problema con un problema:scoprire se una è una potenza di b

Un numero, una, è una potenza di b se è divisibile per b e a/b è un potere di b. Scrivi una funzione chiamata is_power che accetta i parametri aeb e restituisce True se a è una potenza di b.

def is_power(a,b): 
    c = a/b 
    if (((a%b) == 0) and ((c%b) == 0)): 
     return True 
    else: 
     return False 

Sopra è la mia soluzione ma il sistema mi suggerisce di generalizzare la mia soluzione. Qualcuno può dirmi cosa c'è di sbagliato con la mia soluzione?

+0

Non hai davvero bisogno ** di una sola parentesi ** nel tuo "se". Ecco 10 battute inutili che rendono più difficile la lettura del codice. –

risposta

0

Non direi di generalizzare. Direi di correggerlo perché non è corretto. Usando la tua soluzione is_power (12,2) restituisce True così come is_power (18,3).

Penso che il motivo per cui il sistema dice di generalizzare sia che probabilmente funziona correttamente per alcuni dei casi di test, ma non per altri. È probabile che i casi di test per cui sta funzionando coincidano con quelli per cui funzionerebbe se fossero codificati in un certo modo (controllando solo i poteri di 2, ad esempio).

1

Si stanno controllando solo i primi due poteri: a divide b e a/b divide b. Potrebbe essere che a = b ** 3 o b ** 4 (o b ** n in generale), quindi la soluzione effettiva dovrà coinvolgere la ricorsione o un ciclo.

0

si sta controllando se è a/bdivisibile perb (nell'espressione (c%b) == 0), piuttosto che se a/b è un potere dib. Suggerimento: Quale funzione chiamereste per vedere se qualcosa è una potenza di b?

0

Per comprendere la ricorsione, è necessario prima comprendere la ricorsione.

def is_power(a, b): 
    if a < b: # 3 is never a power of 10, right? 
     return False # prevent recursion 
    if a == b: # a is always a**1, right? 
     return True # prevent recursion 
    else: 
     return is_power(a/b, b) # recursion! 

Si noti che per gli interi a/b vi darà errori di arrotondamento. Assicurati di passare i galleggianti.

+0

1 è una potenza di 5 però: p –

+0

Sì, avrei dovuto includere un controllo 'b == 0'. – 9000

+0

Anche ogni numero positivo è un potere fluttuante di qualsiasi numero positivo ... quindi non è possibile utilizzare i float. –

0

Non penso che tu abbia la giusta implementazione. Sulla base del problema, la funzione is_power dovrebbe apparire qualcosa di simile:

def is_power(a,b): 
    if a%b == 0 and is_power(float(a)/float(b), b): 
     return True 
    else: 
     return False 
8

Il motivo motivo per cui il codice originale non funziona è il seguente: basta controllare (c%b) == 0) aka (a/b) is divisible by b, che è molto più debole rispetto alla parte a/b is a power of b della definizione.

Quando si vuole risolvere un problema come questo si dovrebbe sempre iniziare con i casi banali. In questo caso ci sono due casi: is_power(x,x) e is_power(1,x) - in entrambi la risposta è True, perché x**1==x e x**0==1.

Una volta che questi casi sono coperti, è sufficiente scrivere il resto della definizione. Scrivi il codice per (a is divisible by b) and (a/b is a power of b) e metti tutto insieme.

La funzione finale sarà simile a questo:

def is_power(a,b): 
    if <trivial case 1> or <trivial case 2>: 
     return True 
    # its a recursive definition so you have to use `is_power` here 
    return <a is divisible by b> and <a/b is a power of b> 

L'unica domanda che resta è come rispondere <a/b is a power of b>. Il modo più semplice per farlo è utilizzare la funzione is_power stessa, chiamata recursione.

+0

Questa è una risposta corretta al problema che sta cercando di risolvere, ma non è una risposta alla sua domanda, che è stata quella di chiedere cosa non ha funzionato con il suo codice, non come scrivere un codice diverso che risolve il problema. –

+0

Ok, ho aggiunto un po 'più di spiegazione. –

0

È possibile utilizzare il registro.

import math 

def is_power(a, b): 
    return math.log(a, b) % 1 == 0 
+0

'math.log' potrebbe non essere numericamente stabile. –

0
def is_power(a,b): 
    if a == b: 
     return True 
    if a % b == 0 and is_power(a/b,b): 
     return True 
    return False 

La condizione finale che è a == b è cruciale che si arresta quando entrambi numeri sono uguali. Se questo non è incluso, la funzione potrebbe mostrare False anche per numeri legittimi dividendo a/b nella successiva iterazione che dà 1 dove 1% b = 1 che a sua volta restituisce False invece di Vero.

+2

Cerca di offrire qualche spiegazione per la tua risposta invece di fornire semplicemente un blocco di codice. Aiuterà gli altri utenti a capire la risposta invece di correggere un problema localizzato. Grazie! – Conner

+0

Dovresti anche gestire il caso in cui 'b' è zero ma' a' non è perché poi 'a% b == 0' genererà ed eccezione per la divisione per zero che non catturerai. – rbaleksandar

0

Si sta rispondendo al primo vincolo, ma non al secondo,
È verificare che (a/b)%b == 0 che è un caso particolare di "(a/b) is a power of b". Perciò l'errore di generalizzazione (provate a pensare di generalizzare quel caso specifico

Quello che hai scritto non è una soluzione per is power of per esempio si indicano 12 come una potenza di 2 dal:.

  • 12%2 = 0,
  • (12/2)%2 = 0

Ma questo è chiaramente sbagliato.

Come altri hanno detto, pensate alla ricorsione (o alla soluzione di looping meno preferibile).

0

Stavo solo lavorando a questa domanda da solo, e questo è quello che mi è venuto in mente.

Per scrivere questo come una funzione ricorsiva, è necessario la parte ricorsiva e la parte banale. Per la parte ricorsiva, un numero è la potenza di un altro numero se:

((a%b)==0) and (is_power(a/b, b) # a is evenly divisible by b and a/b is also a power of b. 

per il caso banale, b è un potere di a se a=b.

Tuttavia, non abbiamo finito. Poiché dividiamo per b, dobbiamo fare un'eccezione per quando b è zero.

E l'altra eccezione è quando b = 1. Dal momento che quando b=1, a/b è a, ci ritroveremo con una ricorsione infinita.

Quindi, mettendo tutto insieme:

def is_power(a,b): 
    # trivial case 
    if (a==b): return True 

    # Exception Handling 
    if (b==0) or (b==1): return False # unless a==b==0 or a==b==1, which are handled by the trivial case above 

    # recursive case 
    return ((a%b)==0) and (is_power(a/b,b)) 
0

Questo esempio dovrebbe risolvere il problema:

def is_power(a,b): 
if a == 1: 
    return True 
elif a%b == 0 and is_power(a/b, b) == True: 
    return True 
else: 
    return False 
+0

-1 per codice ridondante. La parte 'is_power (a/b, b) == True' è ridondante. 'is_power (a/b, b)' restituisce già un valore booleano. –

0

Ecco la mia soluzione.

def is_power(a,b): 
if a == 1: # base case for recursion 
    return True 
elif b == 0 or a%b !=0 or a<b: # exception cases. 
    return False 
return is_power(a//b,b) # recursion 

ho provato con diversi casi (16,2), (6,2), (1,2), (0,0), (0,1) e funziona bene.

0

Una soluzione molto più semplice è:

def is_power(a, b): 
    while a % b == 0: 
     a //= b 
    return a == 1 

ricorsività non è realmente necessario per questo problema. Inoltre la recusione può causare un errore di limite di ricorsione se a = b ** 1001.

+0

Qual è lo scopo di questa affermazione? a // = b – Kris1511

Problemi correlati