利用python和递归实现赶鸭子问题

发现网上没几个用python实现这个问题的回答(至少我没找到,可能是我搜索功力不行)。所以我就写出来给大伙瞧瞧,不足之处请多多指教!

题目

一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?

要求:
1、使用递归
2、程序输出如下格式:
出发时共赶x只鸭子。
经过第1个村庄卖了y只鸭子,剩余z只鸭。
经过第2个村庄卖了y’只鸭子,剩余z’只鸭。
……
经过第n个村庄卖了Y只鸭子,剩余Z只鸭。

分析

就我个人来看,递归还是比较难用的(像我这种人肯定能不用就不用),不过作业嘛,还是要写的。
据我观察,递归需要两个东西:

  • 终止条件
  • 递归内容

有了上述的概念,我们就来分析题目。利用编程求解这类题的思路都是倒着来,最后剩2只鸭子,那么就卖出去了4只鸭子,那么到第7个村庄时应该还剩下6只鸭子,以此类推,知道了剩下z只鸭子,那么刚到这个村子时就有了 p r e = 2 × ( z + 1 ) pre = 2×(z+1) pre=2×(z+1)只鸭子,卖了 p r e − z pre-z prez只鸭子。思路有了,递归终止条件就出来了,也就是当村庄数等于0的时候,终止递归,结束函数。递归的内容就是村庄数-1,再加上用剩下的鸭子数目求得的刚到这个村子所拥有的鸭子数目。

思路逐渐清晰,我们需要定义一个函数,参数为村子数目CunZiShu和剩下的鸭子数目duck_num,在递归的时候剩下的鸭子数目变为刚到这个村子所拥有的鸭子数目pre,递归的终止条件就是
CunZiShu == 0。

最后来解决输出格式的问题。很容易发现,我们的思路是倒着来的,因此得到的关于鸭子的信息也是倒着来的。因此我的想法是,在函数的参数列表中添加缺省值process=’’,来记录每一次递归的信息,每一次递归的信息加到process前面,并且在前头加上换行符\n,在将新的process添加到参数中,就可以解决信息存储问题。最后在终止条件下加上开头那句然后输出process即可。
万事俱备,来写代码吧!

代码

# 参数为村子数, 剩下的鸭子数和记录的信息,默认为空。
def duck(CunZiShu, duck_num, process=''):
    # 根据剩下的鸭子数目计算刚到这个村时的鸭子数目
    pre = 2*(duck_num+1)
    # 终止条件
    if CunZiShu == 0: 
        process = '出发时共赶{}只鸭子。'.format(duck_num) + process
        # 打印最后结果
        print(process)
    else:
    	# 卖出的鸭子数目
        sell = pre - duck_num
        # 记录信息
        process = '\n经过第{}个村庄卖了{}只鸭子,剩余{}只鸭。'.format(CunZiShu, sell, duck_num) + process
        # 递归内容(上一个村子,上一个村子剩下的鸭子,记录的信息)
        return duck(CunZiShu-1, pre, process) 

duck(7,2)

perfect!来看看运行结果:

出发时共赶510只鸭子。
经过第1个村庄卖了256只鸭子,剩余254只鸭。
经过第2个村庄卖了128只鸭子,剩余126只鸭。
经过第3个村庄卖了64只鸭子,剩余62只鸭。
经过第4个村庄卖了32只鸭子,剩余30只鸭。
经过第5个村庄卖了16只鸭子,剩余14只鸭。
经过第6个村庄卖了8只鸭子,剩余6只鸭。
经过第7个村庄卖了4只鸭子,剩余2只鸭。

这样就获得了结果,代码的复用性也可以,如果改改参数:

duck(8, 3)
出发时共赶1278只鸭子。
经过第1个村庄卖了640只鸭子,剩余638只鸭。
经过第2个村庄卖了320只鸭子,剩余318只鸭。
经过第3个村庄卖了160只鸭子,剩余158只鸭。
经过第4个村庄卖了80只鸭子,剩余78只鸭。
经过第5个村庄卖了40只鸭子,剩余38只鸭。
经过第6个村庄卖了20只鸭子,剩余18只鸭。
经过第7个村庄卖了10只鸭子,剩余8只鸭。
经过第8个村庄卖了5只鸭子,剩余3只鸭。

最后,来一个毫无意义的环节:

def duck(CunZiShu, duck_num, process=''):
	return duck(CunZiShu-1, 2*(duck_num+1), '\n经过第{}个村庄卖了{}只鸭子,剩余{}只鸭。'.format(CunZiShu, 2*(duck_num+1)-duck_num, duck_num) + process) if CunZiShu!=0 else print('出发时共赶{}只鸭子。'.format(duck_num) + process)

虽然没啥意义但以外地很有趣,不是吗?(或许就我这么觉得吧,这也是我喜欢python的一个地方)
行了,这次就到这里吧。欢迎各位指出我的不足。如果有更好的写法也欢迎讨论噢!
本人QQ:1183057296,欢迎交流。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值