2010-09-15 44 views
5

Tôi hiện đang cố gắng để quấn đầu của tôi xung quanh học Python và tôi đã đến một chút của một gian hàng về chức năng đệ quy. Trong Think Python, một trong những bài tập là viết một hàm xác định nếu số một là một sức mạnh của số b sử dụng định nghĩa sau đây:Tại sao hàm đệ quy của tôi trả về Không?

"Một số, một, là một sức mạnh của b nếu nó chia hết cho b và a/b là một lũy thừa của b. Viết một hàm gọi là is_power lấy tham số a và b và trả về True nếu a là một lũy thừa của b. "

Trạng thái hiện tại của chức năng của tôi là:

def isPower(a,b): 
    return a % b == 0 and (a/b) % b == 0 

print isPower(num1,num2) 

Vì nó là, điều này tạo ra kết quả tôi mong đợi. Tuy nhiên, chương này tập trung vào việc viết các hàm đệ quy để giảm sự dư thừa và tôi không hoàn toàn chắc chắn làm thế nào tôi có thể biến "cuối cùng (a/b)% b == 0" thành đệ quy. Tôi đã cố gắng:

def isPower(a,b): 
    if a % b != 0: 
     return False 
    elif isPower((a/b),b): 
     return True 

Nhưng điều đó chỉ trả về Không.

Cách thích hợp để recurse chức năng này là gì?

+3

bạn nên hãy cẩn thận rằng ý nghĩa của toán tử '/' đã thay đổi trong Python 3+, từ trả về một số nguyên để trả về một dấu phẩy, vì vậy mã của bạn sẽ bị ngắt. Thay đổi nó thành '//', nó sẽ luôn trả về một int. –

+2

lưu ý rằng nỗ lực đầu tiên của bạn không kiểm tra xem a là một sức mạnh của b, nó cheks nếu a là bội số của b^2. thử isPower (12,2), nó sẽ trả về True. – Javier

+0

Chỉ cần như vậy, phiên bản đầu tiên của isPower bị hỏng - nó sẽ chỉ cho biết 'a' là bội số của' b^2'. Nó sẽ trả về true cho 'isPower (2, 1)', ví dụ, điều này sẽ không bao giờ đúng. Cho rằng vấn đề, bạn có thể muốn chắc chắn bất kỳ kiểm tra phiên bản đệ quy cho dù '(b == 1 && một! = 1)' trước khi nó tiếp tục, hoặc nó sẽ hoặc gặp khó khăn trong một vòng lặp vô hạn hoặc trả lại điều sai. – cHao

Trả lời

3

Bạn đang quên một trường hợp cơ sở, khi một == 1:

def isPower(a,b): 
    if a == 1: 
     return True 
    if a % b != 0: 
     return False 
    elif isPower((a/b),b): 
     return True 
    else 
     return False 

Tuy nhiên điều này có một số các vấn đề khác - nếu a bằng 0 thì nó sẽ không bao giờ kết thúc và nếu b bằng 0 thì bạn sẽ nhận được phân chia bằng không.

Dưới đây là một giải pháp tiết mà như xa như tôi có thể nói sẽ làm việc cho tất cả các kết hợp số nguyên:

def isPower(a,b): 
    if a == 0 or b == 0: 
     return False 
    def realIsPower(a, b): 
     if a == 1: 
      return True 
     elif a%b != 0: 
      return False 
     elif realIsPower((a/b), b): 
      return True 
     else: 
      return False 
    return realIsPower(a, b) 

EDIT: Mã của tôi đã không làm việc đối với trường hợp khi cả a và b là tiêu cực. Tôi bây giờ so sánh giá trị tuyệt đối của họ.

EDIT2: Silly me, x^0 == 1, vì vậy a == 1 luôn luôn trả về true. Điều đó cũng có nghĩa là tôi không phải so sánh a đến b trước khi đệ quy. Cảm ơn @Javier.

+0

Cảm ơn bạn. Điều này làm rõ chính xác những gì tôi đã mất tích. Sau khi kêu leng keng xung quanh một số chi tiết với nó trước đó tôi đã đạt đến một vòng lặp đệ quy tối đa, nhưng không thể tìm ra cách để ngăn chặn nó. Tôi đoán tôi cho rằng người phiên dịch sẽ biết tôi chỉ muốn nó dừng lại sau khi tự mình thực hiện một lần nữa. Bây giờ tôi hiểu rằng, khi viết một cuộc gọi đệ quy, một trong các bài kiểm tra thậm chí cho phép đạt được nhánh ELIF đó để có thể ngăn chặn nó. Đây chỉ là một chức năng thực hành vì vậy cho phép một cơ sở của 1 sẽ được tốt, nhưng cảm ơn bạn đã đi tất cả ra để giúp đỡ! – bobby

+1

Xin chào, tôi rất vui được giúp đỡ! Luôn nhớ rằng có hai điều cần thiết cho tất cả các hàm đệ quy - một trường hợp cơ bản và một cuộc gọi đệ quy. Đôi khi (chẳng hạn như trong trường hợp này) có nhiều hơn một trường hợp cơ bản. –

2

bạn cần một trường hợp bổ sung, ví khi cả hai điều kiện trả về false

def isPower(a,b): 
    if a % b != 0: 
     return False 
    elif isPower((a/b),b): 
     return True 
    else 
     return False 
+0

Tôi nghĩ bạn có nghĩa là a% b, không phải là một & b – Bob

+0

này sẽ luôn luôn trả về false. –

+0

Bạn cũng cần tính đến trường hợp cơ bản. Tôi vừa chỉnh sửa lỗi đánh máy. –

1
def isPower (a,b): 
    return a==1 or (a!=0 and b!=0 and b!=1 and isPower((a/b),b)) 
+0

này sẽ luôn luôn trả đúng trong trường hợp một ban đầu là 1, tuy nhiên đó chỉ là trường hợp nếu b là 1 hoặc -1. –

+0

Cảm ơn sự giúp đỡ của bạn, Javier. Câu trả lời của bạn và Niki kết hợp chính xác là những gì tôi cần cho mọi thứ để nhấp vào trong đầu tôi. Tôi hiểu tầm quan trọng của giàn giáo và viết code quá dài dòng với nhiều thử nghiệm trên đường đi, nhưng một khi tôi cảm thấy thoải mái với cú pháp và logic Tôi muốn để có thể tạo ra các mã ngắn nhất có thể sản sinh ra tác dụng tương tự. Câu trả lời này là tuyệt vời để xem câu trả lời của Niki trông như một lớp lót để tham khảo trong tương lai. Quá tệ Tôi không thể có hai câu trả lời được chấp nhận! – bobby

+0

@Niki Yoshiuchi: 1 là một sức mạnh của bất kỳ số (x^0 = 1 đối với bất kỳ x) – Javier

0

thử này,

def ispower(a,b): 
    if b==a: 
    return True 
    elif a<b: 
    return False 
    else: 
    return ispower(a*1.0/b, b) 
+0

giải thích sẽ giúp câu trả lời này – dove

1

Đây là mã của tôi. Từ những gì tôi đã thử nghiệm, nó hoạt động:

def ispower(a, b): 

    if b == 1 or b == 0: 
     return False 
    if b <= 0 or a <= 0: 
     return False 
    if a % b == 0: 
     if ((a/b)/b) == 1: 
      return True 
     else: 
      return ispower(a/b, b) 
    else: 
     return False 
     print ispower(-10, 2) 
0
def is_power (a, b): 

    if a == 1: 
     return True 
    if a == 0 and b == 0: 
     return True 
    if a == 0 or b == 0: 
     return False 
    if a%b != 0: 
     return False 
    elif is_power ((a/b), b): 
     return True 
0

Dưới đây là câu trả lời của tôi, đó là một chút bụi:

def is_power(a, b): 
    if a == 1: 
     return True 
    if a == 0 or b == 0: 
     return False 
    if a % b == 0 and is_power(a/b, b): 
     return True 
    else: 
     return False 
Các vấn đề liên quan