简体   繁体   English

如何修复我的代码? 使用递归,返回一个包含所有 k 的列表,使得 3 ≤ k ≤ n 并且 k 可以被 3 或 5 整除,但不能同时被 5 整除?

[英]How can I fix my code? Using recursion, return a list containing all k such that 3 ≤ k ≤ n and k is divisible by 3 or 5 but not both?

So I am reviewing for my class, and as the title suggests I am trying to return a list from a recursive function that includes the positive values divisible by 3 or 5 but not both.所以我正在审查我的 class,正如标题所示,我试图从递归 function 返回一个列表,其中包括可被 3 或 5 整除但不能同时被整除的正值。 So for example, div_by_3_xor_5(20) should return [3, 5, 9, 10, 12, 18, 20] , with 15 being missing because it is divisible by both 3 and 5.因此,例如, div_by_3_xor_5(20)应该返回[3, 5, 9, 10, 12, 18, 20] ,缺少15因为它可以被 3 和 5 整除。

My approach to figuring out recursive solutions is usually to write it as a regular loop first, then see what I need to tweak to turn it into a recursive function.我找出递归解决方案的方法通常是先把它写成一个常规循环,然后看看我需要调整什么来把它变成一个递归 function。 The regular loop function of this is simple enough:这个的常规循环 function 很简单:

def div_by_3_xor_5(n):
    a_list = []
    for i in range(3, n + 1):
        div_by_3 = (i % 3 == 0)
        div_by_5 = (i % 5 == 0)
        
        if div_by_3 and div_by_5:
            pass
        elif div_by_3 or div_by_5:
            a_list.append(i)
    return a_list

# correct output for div_by_3_xor_5(20): [3, 5, 9, 10, 12, 18, 20]

I have tried converting it into a recursive function but the output is wrong.我尝试将其转换为递归 function 但 output 是错误的。

def div_by_3_xor_5(n, k = 3):
    if k >= n:
        return [n]
    
    for i in range(k, n + 1):
        div_by_3 = (i % 3 == 0)
        div_by_5 = (i % 5 == 0)
        
        if div_by_3 and div_by_5:
            pass
        elif div_by_3 or div_by_5:
            return [i] + div_by_3_xor_5(n, k + 1)
    
# incorrect output for div_by_3_xor_5(20): 
# [3, 5, 5, 6, 9, 9, 9, 10, 12, 12, 18, 18, 18, 18, 18, 18, 20, 20]

Could anyone help me figure out what's going wrong, so that I return [3, 5, 6, 9, 10, 12, 18, 20] instead?谁能帮我找出问题所在,以便我返回[3, 5, 6, 9, 10, 12, 18, 20]吗?

def div_by_3_xor_5(n, k = 3):
    if k >= n:
        return [n]
    
    div_by_3 = (k % 3 == 0)
    div_by_5 = (k % 5 == 0)
        
    if div_by_3 and div_by_5:
        return div_by_3_xor_5(n, k + 1)
    elif div_by_3 or div_by_5:
        return [k] + div_by_3_xor_5(n, k + 1)
    else:
        return div_by_3_xor_5(n, k + 1)

# output of div_by_3_xor_5(20) was correct: [3, 5, 6, 9, 10, 12, 18, 20]

I figured it out after looking at my code again thanks to Karl's comment.感谢 Karl 的评论,我在再次查看我的代码后发现了这一点。 I was trying to loop over the integers not divisible by either 3 or 5, but I could've done that with a recursive call to the next integer.我试图遍历不能被 3 或 5 整除的整数,但我可以通过递归调用下一个 integer 来做到这一点。 Thank you Karl!谢谢卡尔!

You somehow need to make the recursion act on a smaller piece of the problem each time.您每次都需要以某种方式使递归作用于问题的一小部分。

Here's a divide-and-conquer form of recursion, although it's a real stretch to force-fit recursion into this requirement in my view.这是一种分而治之的递归形式,尽管在我看来,将递归强制适应此要求是一个真正的延伸。

def wacky_numbers(hi, lo=3):
    if hi == lo:
        test3 = lo%3 == 0
        test5 = lo%5 == 0
        if test3 != test5:
            return [lo]
        else:
            return []
    else:
        mid = (hi+1+lo)//2
        return wacky_numbers(mid-1,lo) + wacky_numbers(hi,mid)

For extra protection you might want to test hi<lo为了获得额外的保护,您可能需要测试hi<lo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM