【问题标题】:Recursive function to know if a number is divisible by 3递归函数判断一个数是否能被 3 整除
【发布时间】:2019-12-11 08:49:28
【问题描述】:

我需要创建一个递归函数,如果输入的数字可以被 3 整除,则返回 true。我知道没有递归会更简单,但我需要创建一个这种类型的函数。

我已经创建了一个函数,但我想知道是否可以创建一个更好的函数,因为'num' 很大,该函数不起作用。我认为我应该使用这个事实:如果自然数的数字之和可以被 3 整除,那么自然数可以被 3 整除。

这是我的代码:

def divThree(num):
    if num==3:
        return true
    else:
        divThree(num-3)

编辑:我创建了一个更好的函数,但我不明白如果数字可以被三整除,为什么不返回 true。相反,如果不是,则继续最大递归错误。

def recursiveThree(num):
  if num==3 or num==6 or num==9:
    return true
  else:
    sum=0
    sNum=str(num)
    for i in range(0,len(sNum)):
      sum=sum+int(sNum[i])
    recursiveThree(sum)

【问题讨论】:

  • return num % 3 != 0
  • 您没有指定错误或输入的数字有多大,但假设数字是 15 次方或以上的正整数,我认为您可能会得到最大递归深度限制到达错误。这就是我们想要解决的问题,因此我们相应地优化了我们的代码。
  • 为什么你的函数需要递归?这是一个排除明显和合理的解决方案的要求,只留下特殊的、破碎的、低效的和不自然的解决方案(特别是因为 Python 不进行尾递归,并且对递归级别设置了相当低的限制)。如果这是一项任务,那就太糟糕了。
  • 这是一个大学练习,所以我必须使用递归,如果它更好,使用 for cicle 更简单
  • @user8024584:好的,但这仍然是一个奇怪的要求,没有更多细节。例如:def divisible_by_three(n): return n % 3 == 0 if random.random() < 0.1 else divisible_by_three(n) 满足使用递归的要求,但几乎可以肯定不是您的讲师想要的。

标签: python python-2.7 math recursion division


【解决方案1】:
  • 最直接的解决方案是使用模 3 来检查 可分性,但这不会是递归的。
  • 另一种解决方案是递归地继续除以 3,直到降至 1,但对于较大的值,这会导致堆栈溢出。
  • 适用于递归的第三种解决方案是利用一个属性,即如果一个数字的数字之和可以被 3 整除,则该数字可以被 3 整除。

这是第三个选项的实现,它避免了模运算并处理非常大的数字:

def divThree(num):
    if num < 10:
        return (num in [3, 6, 9])
    else:
        return divThree(sum([int(digit) for digit in str(num)]))

如果您想将第一个 return 的列表也视为可被 3 整除,则可以将 0 添加到列表中。

如果您想同时容纳正值和负值,请在前面添加:

if num < 0:
    return divThree(-num)

作为要执行的第一个检查。

【讨论】:

  • 很好的答案,考虑到特殊的要求。可能值得注意的是,即使divThree 对于非常大的数字(例如10**10**6)也比% 3 检查效率低得多,因为 int -> str 转换需要时间二次方位数。 (对于10**10**6divThree 的时间为 13.7 秒,而基于 %3 的简单函数为 0.00143 秒。我不敢尝试输入 10**10**7divThree。:-)
【解决方案2】:

使用3作为除数时,需要检查数的余数是否为零。

使用% 运算符检查余数。因此,如果您想查看是否可以被 3 整除,请使用 num % 3 == 0 如果余数为零,则该数字可以被 3 整除。

这返回真:

print (6 % 3 == 0)
returns True

这返回 False:

print (5 % 3 == 0)
returns False

这是一个检查真假的简单函数:

def divThree(numb):
    return numb % 3 == 0

print (divThree(99))

编辑:

我不确定您要检查的数字有多大,但我用我认为很大的数字测试了这个函数并且它有效。我可能只是不明白你需要思考什么。

def divThree(numb):
    return numb % 3 == 0

print (divThree(4325609549876542987503216540321540104986213754901245217346214390735402153407213540213457183254098263487053214132754073254921534987053245321454))

Returned True

【讨论】:

    【解决方案3】:

    你递归地放大要减去的因子:

    def divisible_by_tree(num, factor=3):
        if factor < num:
            num = divi(num, factor * 2)
        if num >= factor:
            num -= factor
        if factor > 3:
           return num
        return num == 0
    

    【讨论】:

    • if factor &gt; 3,真的吗?
    【解决方案4】:

    这是一种晦涩难懂的方法,有几个更好的答案,但是实现同余定理,你可以说:

    from random import randint # For test trials
    
    def isDivisByThree(n):
        sN = str(n)
        if(len(sN) == 1):
            bIsProductOfThree=True if(n==3 or n==6 or n==9) else False
            return bIsProductOfThree
        else:
            sumOfDigits = 0
            for x in sN:
                sumOfDigits += int(x)
            # end for
            return isDivisByThree(sumOfDigits)
        # end if
    # end isDivisByThree(...)
    
    def main():
        for testTrialCount in range(1, 35+1):
            testSubject = randint(1, 2147483647)
            result = isDivisByThree(testSubject)
            if(result):
                print("Test Trial #" + str(testTrialCount) + ": " + str(testSubject) + " is divisble by 3!")
            else:
                print("Test Trial #" + str(testTrialCount) + ": " + str(testSubject) + " is NOT divisble by 3.")
            # end if
        # end for
    # end main()
    
    main()
    

    这是因为与同余应用相关的一个定理:如果 d|(b-1) 那么 n = (a_k * ... * a_1 * a_0) 可以被 d 当且仅当数字的总和 a_k + ... + a_1 + a_0 可以被 d 整除。 (其中d 是除数(本例中为 3),b 是表示数字的基数(本例中为 10)。

    前 10 次试验的示例输出:

    Test Trial #1: 458327921 is NOT divisble by 3.
    Test Trial #2: 23787660 is divisble by 3!
    Test Trial #3: 820562190 is divisble by 3!
    Test Trial #4: 1466915534 is NOT divisble by 3.
    Test Trial #5: 1395854683 is NOT divisble by 3.
    Test Trial #6: 1844052852 is divisble by 3!
    Test Trial #7: 261731131 is NOT divisble by 3.
    Test Trial #8: 624183104 is NOT divisble by 3.
    Test Trial #9: 788686237 is NOT divisble by 3.
    Test Trial #10: 1075010016 is divisble by 3!
    ...
    

    编辑

    啊,我看到 pjs 用类似的解决方案打败了我。

    【讨论】:

      【解决方案5】:

      您可以使用模数找出数字可以被 3 整除,然后将其减去 num

       def divThree(num):
            if num % 3 == 0:
              return True
            a = num % 3
            return divThree(num-a)
      

      【讨论】:

      • 第2行的变量“n”是什么?
      • 应该是变量 num 而不是 n
      • 这将始终返回 True。取 num = 11, a = 2, num - a = 9。
      【解决方案6】:

      C 语言(易于翻译)

      bool divisible_by_three (int x) {
          if (x < 0) return divisible_by_three (-x);
          else if (x >= 3) return divisible_by_three (x % 3);
          else return (x == 0);
      }
      

      是的,它是递归的。为您的教练做的练习:找出错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-25
        • 2018-01-16
        • 1970-01-01
        • 2012-11-14
        • 2013-11-05
        • 1970-01-01
        • 2010-10-25
        • 2014-01-04
        相关资源
        最近更新 更多