zoukankan      html  css  js  c++  java
  • 递归

    递归

    假设你在祖母的阁楼中发现一个上锁的神秘手提箱。

    祖母告诉你,钥匙可能在下面这个盒子中。

    这个盒子里有盒子,而盒子里的盒子又有盒子。钥匙就在某个盒子中。
    为找到钥匙,你将使用什么算法?先想想这个问题,再接着往下看。

    第一种方法使用的是while循环:只要
    盒子堆不空,就从中取一个盒子,并在其中仔细查找。

    def look_for_key(main_box):
    	pile = main_box.make_a_pile_to_look_through()
    	while pile is not empty:
    		box = pile.grab_a_box()
    		for item in box:
    			if item.is_a_box():
    				pile.append(item)
    			elif item.is_a_key():
    				print "found the key!"
    

    第二种方法使用递归——函数调用自己,这种方法的伪代码如下。

    def look_for_key(box):
    	for item in box:
    		if item.is_a_box():
    

    这两种方法的作用相同,但在我看来,第二种方法更清晰。递归只是让
    解决方案更清晰,并没有性能上的优势。实际上,在有些情况下,使用
    循环的性能更好。我很喜欢Leigh Caldwell在Stack Overflow上说的一句
    话:“如果使用循环,程序的性能可能更高;如果使用递归,程序可能
    更容易理解。如何选择要看什么对你来说更重要。

    基线条件和递归条件

    由于递归函数调用自己,因此编写这样的函数时很容易出错,进而导致
    无限循环。例如,假设你要编写一个像下面这样倒计时的函数。

    > 3 ... 2 ... 1

    为此,你可以用递归的方式编写,如下所示:

    def countdown(i):
    	print i
    	countdown(i-1)
    

    如果你运行上述代码,将发现一个问题:这个函数运行起来没完没了!

    3...2...1...0...-1...-2...等等

    编写递归函数时,必须告诉它何时停止递归。正因为如此,每个递归函
    数都有两部分:基线条件(base case)和递归条件(recursive case)。
    递归条件指的是函数调用自己,而基线条件则指的是函数不再调用自
    己,从而避免形成无限循环。
    我们来给函数countdown添加基线条件。

    def countdown(i):
    	print i
    	if i <= 1: ←------基线条件
    		return
    	else: ←------递归条件
    	countdown(i-1)
    

    现在,这个函数将像预期的那样运行,如下所示。

  • 相关阅读:
    MS17-010(永恒之蓝)远程溢出漏洞
    SQL注入实战之盲注篇(布尔、时间盲注)
    kali下vulhub的使用
    SQL注入实战之报错注入篇(updatexml extractvalue floor)
    SQL注入实战之联合查询篇(含漏洞网站搭建)
    apache/nginx/IIS日记记录分析
    nvcatmysql的安装
    乌云(wooyun)虚拟机的搭建复活
    Web安全基础笔记
    公告、留言
  • 原文地址:https://www.cnblogs.com/zzsy/p/12684807.html
Copyright © 2011-2022 走看看