趣学Python算法100例-1.2 兔子产子

完整源代码项目地址,关注私信’源代码’后可获取

1.问题描述

有一对兔子,从出生后的第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子,假设所有的兔子都不死,问30个月内每个月的兔子总对数为多少?

2.问题分析

兔子产子问题是一个有趣的古典数学问题,我们画一张表来找一下兔子数的规律,如表1.1所示。

趣学Python算法100例-1.2 兔子产子_第1张图片

说明:不满1个月的兔子为小兔子,满1个月不满2个月的为中兔子,满3个月以上的为老兔子。

可以看出,每个月的兔子总数依次为1,1,2,3,5,8,13…这就是Fibonacci数列。总结数列规律即为从前两个月的兔子对数可以推出第3个月的兔子对数。

3.算法设计

本题目是典型的迭代循环,即是一个不断用新值取代变量的旧值,然后由变量旧值递推出变量新值的过程。这种迭代与这些因素有关:初值、迭代公式和迭代次数。经过问题分析,算法可以描述为

趣学Python算法100例-1.2 兔子产子_第2张图片

用Python语言来描述迭代公式即为fib=fib1+fib2,其中fib为当前新求出的兔子对数,fib1为前一个月的兔子对数,fib2为前两个月的兔子对数,然后为下一次迭代做准备,如图所示

在这里插入图片描述

进行如下的赋值fib2=fib1,fib1=fib,要注意赋值的次序;迭代次数由循环变量控制,为所求的月数。

4.完整的程序

根据上面的分析,编写程序如下:

%%time 
# 兔子产子问题

if __name__=="__main__":
    fib1 = 1
    fib2 = 1
    i = 3
    # 输出第一个月和第二个月的兔子对数
    print("%6d       %6d" %(fib1, fib2), end="       ")
    while i <= 30:
        fib = fib1 + fib2                           # 迭代求出当前月份的兔子对数
        print("%6d" %fib, end="       ")            # 输出当前月份的兔子对数
        if i % 4 == 0:
            print()                                 # 每行输出4个
        fib2 = fib1                                 # 为下一次迭代做准备,求出新的fib2
        fib1 = fib                                  # 求出新的fib1
        i += 1


     1            1            2            3       
     5            8           13           21       
    34           55           89          144       
   233          377          610          987       
  1597         2584         4181         6765       
 10946        17711        28657        46368       
 75025       121393       196418       317811       
514229       832040       CPU times: user 854 µs, sys: 970 µs, total: 1.82 ms
Wall time: 896 µs

6.问题拓展

这个程序虽然是正确的,但可以进行改进。目前用3个变量来求下一个月的兔子对数,其实可以在循环体中一次求出下两个月的兔子对数,这样就可以只用两个变量来实现。这里将fib1+fib2的结果不放在fib中而是放在fib1中,此时fib1不再代表前一个月的兔子对数,而是代表最新一个月的兔子对数,再执行fib2=fib1+fib2,由于此时fib1中已经是第3个月的兔子对数了,故fib2中就是第4个月的兔子对数。可以看出,此时fib1和fib2均为最近两个月的兔子对数,循环推出下两个月的兔子对数。改进后的程序如下:

%%time
# 兔子产子问题

if __name__=="__main__":
    fib1 = 1
    fib2 = 1
    i = 1
    while i <= 15:     #每次求两个,因此循环变量循环到15
        print("%8d    %8d" %(fib1, fib2), end="      ")
        if i % 2 == 0:
            print()
        fib1 = fib1 + fib2                                  # 最新一个月的兔子对数
        fib2 = fib1 + fib2                                  # 第4个月的兔子对数
        i += 1

       1           1             2           3      
       5           8            13          21      
      34          55            89         144      
     233         377           610         987      
    1597        2584          4181        6765      
   10946       17711         28657       46368      
   75025      121393        196418      317811      
  514229      832040      CPU times: user 294 µs, sys: 0 ns, total: 294 µs
Wall time: 290 µs

你可能感兴趣的:(趣学Python算法100例,python,算法,开发语言)