python日记_递归

递归算法

1、递归的定义 
递归就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。 
递归常与分治思想同时使用,能产生许多高校的算法。递归常用来解决结构相似的问题。所谓结构相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有直接的解法;第二部分与原问题相似,但比原问题的规模小,并且依赖第一部分的结果。。实际上,递归是把一个不能或不好解决的大问题转化成一个或几个小问题,再把这些小问题进一步分解成更小的小问题,直至每个小问题都可以直接解决。因此,递归有两个基本要素: 
(1) 边界条件:确定递归到何时终止,也称为递归出口。 
(2) 递归模式:大问题是如何分解为小问题的,也称为递归体。 
递归函数只有具备了这两个要素,才能在有限次计算后得出结果。 
2、递归算法实例

2.1求一个整数n的阶乘 
阶乘的定义如下图:

根据阶乘的递归定义,很容易就能写出求阶乘的递归算法。

def factorial(n) :
  if n == 1 :
    return 1         #递归结束
  return n * factorial(n - 1)  #问题规模减1,递归调用

2.2汉诺塔 
汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶。所有碟子按从大到小的次序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔B和C。从世界创始之日起,波罗门的牧师就一直在试图把塔A上的碟子移动到C上去,其间借助于塔B的帮助。每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。当牧师们完成这个任务时,世界末日也就到了。 
对于汉诺塔问题的求解,可以通过以下3步实现: 
(1)将塔A上的n -1个碟子借助C塔先移动到B塔上; 
(2)把塔A上剩下的一个碟子移动到塔C上; 
(3)将n - 1个碟子从B塔借助塔A移动到塔C上。 
很显然,这是一个递归求解的过程,假设碟子数n=3时,汉诺塔问题的求解过程如下图所示:

汉诺塔的递归算法(Python实现):

def Hanoi(n, A, B, C) :
  if (n == 1) :
    move(A, c)   #表示只有一个碟子时,直接从A塔移动到C塔
  else :
    Hanoi(n - 1, A, C, B)  #将剩下的A塔上的n-1借助C塔移动到B塔
    move(A, C)              #将A上最后一个直接移动到C塔上
    Hanoi(n - 1, B, A, C)  #将B塔上的n-1个碟子借助A塔移动到C塔
 

递归函数的运行轨迹 
借助汉诺塔这个实例,来讲解一下递归函数的运行轨迹。在递归函数中,调用函数和被调用函数都是同一个函数,需要注意的是函数的调用层次,如果把调用递归函数的主函数称为第0层,进入函数后,首次递归调用自身称为第1层调用;从第i层递归调用自身称为第i+1层。反之退出i+1层调用应该返回第i层。下图是n=3时汉诺塔算法的运行轨迹,有向弧上的数字表示递归调用和返回的执行顺序。

汉诺塔的递归算法代码实现:

#coding=utf-8

i = 1
def move(n, mfrom, mto) :
  global i
  print "第%d步:将%d号盘子从%s -> %s" %(i, n, mfrom, mto)
  i += 1

def hanoi(n, A, B, C) :
  if n == 1 :
    move(1, A, C)
  else :
    hanoi(n - 1, A, C, B)
    move(n, A, C)
    hanoi(n - 1, B, A, C)

#********************程序入口**********************
try :
  n = int(raw_input("please input a integer :"))
  print "移动步骤如下:"
  hanoi(n, ‘A‘, ‘B‘, ‘C‘)
except ValueError:
  print "please input a integer n(n > 0)!" 
 

执行结果: 

2.3 斐波拉契数列 
斐波拉契数列,是这样的一个数列:0、1、1、2、3、5、8、13、21、……。 
斐波拉契数列的核心思想是: 
从第三项起,每一项都等于前两项的和,即F(N) = F(N - 1) + F(N - 2) (N >= 2) 
并且规定F(0) = 0,F(1) = 1

要求:利用递归算法获得指定项的斐波拉契数列。

#!/usr/bin/python
#coding=utf-8
def fib_list(n) :
  if n == 1 or n == 2 :
    return 1
  else :
    m = fib_list(n - 1) + fib_list(n - 2)
    return m
print "**********请输入要打印的斐波拉契数列项数n的值***********"
try :
  n = int(raw_input("enter:"))
except ValueError :
  print "请输入一个整数!"
  exit()
list2 = [0]
tmp = 1
while(tmp <= n):
  list2.append(fib_list(tmp))
  tmp += 1
print list2
 

执行结果: 

时间: 2024-10-24 13:44:54

python日记_递归的相关文章

python日记_切片

先从原理上分析切片运算: list的切片,内部是调用__getitem__,__setitem__,__delitem__和slice函数.而slice函数又是和range()函数相关的. 给切片传递的键是一个特殊的slice对象.该对象拥有可描述所请求切片方位的属性,例如: a = [ 1, 2, 3, 4, 5, 6 ] x = a [ 1 : 5 ] # x = a.__getitem__( slice ( 1, 5, None ) ) a [ 1 : 3 ] = [10, 11, 12

python 内置&&递归

lambda 优点: 1:可以简单使用一个脚本来替代我们的函数 2:不用考虑命名的问题 3:简化代码的可读性,不用跳转到def了,省去这样的步骤 内置函数:bif filter:过滤器 map:映射  1 >>> lambda x: 2*x+1 2 <function <lambda> at 0x00000000026C6AC8> 3 >>> g=lambda x: 2*x+1 4 >>> g(3) 5 7 6 >>

Python的最大递归深度错误 “maximum recursion depth exceeded while calling a Python object”

今天在写爬虫的时候,发现了一个诡异的事情,使用str方法强制转换一个BeautifulSoup对象成字符串的时候报错了,提示是"maximum recursion depth exceeded while calling a Python object",意思大致是"当调用该对象超过最大递归深度" 报错如下:   Traceback (most recent call last):   File "<stdin>", line 1, 

python中_、__和__xx__的区别

python中_.__和__xx__的区别 本文为译文,版权属于原作者,在此翻译为中文分享给大家. 英文原文地址:Difference between _, __ and __xx__ in Python 在学习Python时,很多人都弄不清楚各种下划线的意思,而且在这之前已经给其他人解释过很多遍了,是时候把它记录下来. "_"单下划线 Python中不存在真正的私有方法.为了实现类似于c++中私有方法,可以在类的方法或属性前加一个“_”单下划线,意味着该方法或属性不应该去调用,它并不

python开发_++i,i += 1的区分

python开发_++i,i += 1的区分 在很多编程语言(C/C++,Java等)中我们都会碰到这样的语法: 1 int i = 0; 2 ++ i; // -- i; 这样的语法在上述编程语言中可以实现自增(减),在python中也支持这样的语法,不过在python中 这样的用法不是用来自增(减),而是实现数学中的符号运算操作: 1 i = 2 2 ++ i #输出:2 3 +(+i) #输出:2 4 -(+i) #输出:-2 5 +(-i) #输出:-2 6 -(-i) #输出:2 在p

量化分析师的Python日记【第1天:谁来给我讲讲Python?】

量化分析师的Python日记[第1天:谁来给我讲讲Python?]薛昆Kelvin优矿 001 号员工2015-01-28 15:48 58 144克隆 ###“谁来给我讲讲Python?” 作为无基础的初学者,只想先大概了解一下Python,随便编个小程序,并能看懂一般的程序,那些什么JAVA啊.C啊.继承啊.异常啊通通不懂怎么办,于是我找了很多资料,写成下面这篇日记,希望以完全初学者的角度入手来认识Python这个在量化领域日益重要的语言 ###一,熟悉基本 在正式介绍python之前,了解

Python学习_列表解析和Lambda表达式

1.根据要求创建列表threes_and_fives(列表值包括1到15中能够被3或者5正常的数) threes_and_fives=[x for x in range(1,16) if x%3==0 or x%5==0] 2.lambda表达式实例(剔除掉列表中的"X") garbled = "IXXX aXXmX aXXXnXoXXXXXtXhXeXXXXrX sXXXXeXcXXXrXeXt mXXeXsXXXsXaXXXXXXgXeX!XX" message

python日记___name__ == &#39;__main__&#39;

在大多数编排得好一点的脚本或者程序里面都有这段if __name__ == 'main': ,虽然一直知道他的作用,但是一直比较模糊,收集资料详细理解之后与大家分享. 1.这段代码的功能 一个python的文件有两种使用的方法,第一是直接作为脚本执行,第二是import到其他的python脚本中被调用(模块重用)执行.因此if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本

python练习_购物车(简版)

python练习_购物车(简版) 需求: 写一个python购物车可以输入用户初始化金额 可以打印商品,且用户输入编号,即可购买商品 购物时计算用户余额,是否可以购买物品 退出结算时打印购物小票 以下代码实现的功能与思路: 功能: (1)预算金额控制,只能输入大于0的数字 (2)商品格式化打印 (3)选择完成要买的商品后,提示用户再次确认,确认后开始计算用户余额是否大于等于商品价格,价格正确后则加入购物车 (4)输入q则进行结算,结算时将重复的商品进行合并,显示个数,并计算消费总额和余额 思路: