递归 python

  ↵一、简单理解

解决问题的一种方法,它将问题不断的分成更小的子问题,直到子问题可以用普通的方法解决。通常情况下,递归会使用一个不停调用自己的函数。

【注】:每一次递归调用都是在解决一个更小的问题,如此进行下去,直到问题本身不能在简化为止

例子:

1.列表元素之和

# 求列表元素之和
def sumList(numlist):
    '''
    循环计算列表和
    :param numlist:数值列表
    :return: 和
    '''
    sum = 0
    for num in numlist:
        sum += num
    return sum


def listnum(numlist):
    '''
    递归计算列表和
    :param numlist: 数值列表
    :return: 和
    '''
    if len(numlist) == 1:
        return numlist[0]
    else:
        return numlist[0] + listnum(numlist[1:])


if __name__ == "__main__":
    numlist = [1, 2, 3, 4, 5, 6]
    a = sumList(numlist)
    b = listnum(numlist)
    print("循环计算结果:%f,递归计算结果:%f" % (a, b))

2.整数转换进制

# 将整数转换成以2-16为进制基数的字符串
def toStr(n, base):
    '''
    将输入的整数n转换成2-16任意进制的字符串
    :param n: 任意正整数
    :param base: 2-16中进制
    :return: 转换好的字符串
    '''
    convertString = "0123456789ABCDEF"
    if n < base:
        return convertString[n]
    else:
        return toStr(n // base, base) + convertString[n % base]


if __name__ == "__main__":
    n = 10
    base = 2
    print("十进制数:%d 转换成二进制数:%s" % (n, toStr(n,base)))#字符的拼接

另外不使用字符拼接的方式

from main import Stack

# 将整数转换成以2-16为进制基数的字符串
rStack = Stack()


def toStr(n, base):
    '''
    将输入的整数n转换成2-16任意进制的字符串,不使用字符拼接,而是通过栈帧
    :param n: 任意正整数
    :param base: 2-16中进制
    :return: 转换好的数值存储栈帧
    '''
    convertString = "0123456789ABCDEF"
    if n < base:
        rStack.push(convertString[n])
    else:
        rStack.push(convertString[n % base])
        toStr(n // base, base)
    return rStack


if __name__ == "__main__":
    n = 100
    base = 2
    numStack = toStr(n, base)
    print("整数%d转换为%d进制为:" % (n, base), end="")
    while numStack.size() >= 1:
        print(numStack.pop(), end="")

二、可视化

使用python中的画图工具进行简单递归程序的绘画,从而理解递归的概念

1.螺旋线

#用turtle模块递归的绘制螺旋线
from turtle import *

myTurtle = Turtle()
myWin = myTurtle.getscreen()


def drawSpiral(myTurtle, lineLen):
    if lineLen > 0:
        myTurtle.forward(lineLen)
        myTurtle.right(90)
        drawSpiral(myTurtle, lineLen - 5)


drawSpiral(myTurtle, 100)
myWin.exitonclick()#用户在窗口内再次点击之后,程序清理并退出

2.分形树

#无法绘画出来的
from turtle import *

myTurtle = Turtle()
myWin = myTurtle.getscreen()


def tree(brancheLen, t):
    if brancheLen > 5:
        t.forward(brancheLen)
        t.right(20)
        tree(brancheLen-15,t)
        t.left(40)
        tree(brancheLen-10,t)
        t.right(20)
        t.backward(brancheLen)

t = Turtle()
myWin = t.getscreen()
t.left(90)
t.up()
t.backward(100)
t.down
tree(110,t)
myWin.exitonclick()

chatGPT中给的代码

#能绘画出来
import turtle

def draw_branch(t, length):
    if length > 5:
        t.forward(length)  # 绘制主干
        t.right(20)  # 右转一定角度
        draw_branch(t, length - 15)  # 递归绘制右侧分支
        t.left(40)  # 左转一定角度
        draw_branch(t, length - 15)  # 递归绘制左侧分支
        t.right(20)  # 右转一定角度
        t.backward(length)  # 返回原点

def main():
    # 设置窗口和画笔
    window = turtle.Screen()
    window.bgcolor("white")
    t = turtle.Turtle()
    t.speed(0)  # 设置绘制速度为最快

    # 调整画笔位置和方向
    t.left(90)
    t.up()
    t.backward(200)
    t.down()

    # 绘制分形树
    draw_branch(t, 100)

    # 等待用户点击关闭窗口
    turtle.mainloop()

if __name__ == "__main__":
    main()

3.谢尔平斯基三角形

chatGPT所给的代码---可运行

import turtle

def draw_triangle(t, order, size):
    if order == 0:
        for _ in range(3):
            t.forward(size)
            t.left(120)
    else:
        draw_triangle(t, order - 1, size / 2)
        t.forward(size / 2)
        draw_triangle(t, order - 1, size / 2)
        t.backward(size / 2)
        t.left(60)
        t.forward(size / 2)
        t.right(60)
        draw_triangle(t, order - 1, size / 2)
        t.left(60)
        t.backward(size / 2)
        t.right(60)

def main():
    # 设置窗口和画笔
    window = turtle.Screen()
    window.bgcolor("white")
    t = turtle.Turtle()
    t.speed(0)  # 设置绘制速度为最快

    # 调整画笔位置和方向
    t.up()
    t.goto(-200, -150)
    t.down()

    # 绘制谢尔平斯基三角形
    draw_triangle(t, 5, 400)

    # 隐藏画笔
    t.hideturtle()

    # 等待用户点击关闭窗口
    turtle.mainloop()

if __name__ == "__main__":
    main()

b站上所学

# 绘制谢尔平斯基三角形
#B站--python递归三部曲(基于turtle实现可视化)
import turtle

t = turtle.Turtle()


def get_midpoint(a, b):
    '''
    得到两点的中点坐标
    :param a: 坐标点(元组)
    :param b: 坐标点(元组)
    :return: 中点坐标(元组)
    '''
    ax, ay = a
    bx, by = b
    return ((ax + bx) / 2, (ay + by) / 2)


def draw_triangle(a, b, c):
    '''
    绘制以a,b,c为顶点的三角形
    :param a: 顶点坐标(元组)
    :param b: 顶点坐标(元组)
    :param c: 顶点坐标(元组)
    :return: 无返回值
    '''
    ax, ay = a
    bx, by = b
    cx, cy = c

    t.penup()  # 提起画笔
    t.goto(a)  # 画笔移动到a点的位置
    t.pendown()  # 落下画笔
    t.goto(b)  # 画出ab线段
    t.goto(c)  # 画出bc线段
    t.goto(a)  # 画出ca线段

    t.penup()


def draw_sierpinski(triangle, depth):
    a, b, c = triangle  # triangle包括三个顶点的元组
    draw_triangle(a, b, c)

    if depth == 0:
        return
    else:
        d = get_midpoint(a, b)
        e = get_midpoint(b, c)
        f = get_midpoint(c, a)
        adf = (a, d, f)
        dbe = (d, b, e)
        fec = (f, e, c)
        draw_sierpinski(adf, depth - 1)
        draw_sierpinski(dbe, depth - 1)
        draw_sierpinski(fec, depth - 1)

if __name__ == "__main__":
    triangle = ((-200,-100),(0,200),(200,-100))
    draw_sierpinski(triangle,4)

4.汉诺塔

不能可视化的

#B站---python递归三部曲(基于turtle实现可视化)
#汉诺塔
def moveDisk(diskIndex,fromPole,toPole):
    '''
    从起始塔向目标塔移动圆环
    :param diskIndex:圆环
    :param fromPole:起始塔
    :param toPole:目标塔
    :return:无
    '''
    print_str = 'Move disk %s from %s to %s' %(diskIndex,fromPole,toPole)
    print(print_str)

def moveTower(height,fromPole,withPole,toPole):
    '''
    汉诺塔的递归调用函数
    :param height: 汉诺塔高度
    :param fromPole: 起始塔
    :param withPole: 中转塔
    :param toPole: 目标塔
    :return:
    '''
    if height == 1:
        moveDisk(1,fromPole,toPole)
    else:
        moveTower(height-1,fromPole,toPole,withPole)
        moveDisk(height,fromPole,toPole)
        moveTower(height-1,withPole,fromPole,toPole)

if __name__ == "__main__":
    moveTower(3,"A","B","C")

能可视化的

#自己对着B站视频写的一半,但是无法正确跑,不过注释都是正确的意思
import turtle


def set_plate(i):
    '''
    绘制第i层圆盘
    :return:
    '''
    size = 20  # 圆盘转弯半径基数
    l = size * (i + 2)  # 第i层圆盘半径

    t = turtle.Turtle()
    t.hideturtle()  # 隐藏画笔
    t.penup()  # 提起画笔

    t.left(90)  # 每次先逆时针旋转90度,新建的左转90度为设置时的图案。
    t.begin_poly()  # 绘制记录
    t.forward(l)  # 向前走40
    t.circle(size, 180)  # 画一个半径为20,角度为180的弧
    t.forward(l * 2)
    t.circle(size, 180)
    t.forward(l)
    t.end_poly()  # 结束记录

    turtle.register_shape("plate_%s" % i, p)  # 取出记录的情况,给不同层的圆盘赋值不同的名称


def set_tower():
    '''
    绘制塔
    :return:
    '''
    # 塔的参数:宽、高、转弯半径
    tower_width = 100
    tower_height = 200
    tower_radius = 10

    t = turtle.Turtle()
    t.hideturtle()  # 隐藏画笔
    t.penup()  # 提起画笔

    t.left(90)
    t.begin_poly()
    t.forward(tower_width)
    t.circle(tower_radius, 180)
    t.forward(tower_width - tower_radius)
    t.right(90)
    t.forward(tower_height)
    t.circle(tower_radius, 180)
    t.forward(tower_height)
    t.right(90)
    t.forward(tower_width - tower_radius)
    t.circle(tower_radius, 180)
    t.forward(tower_width)
    t.end_poly()
    turtle.register_shape("tower")


def draw_towers():
    # 塔的参数:塔之间的距离,塔的海拔高度
    tower_distance = 250
    tower_altitude = -100
    set_tower()
    tower = turtle.Turtle("tower")
    tower.speed(0)  # 0是最快的速度
    tower.penup()
    tower.goto(-tower_distance, tower_altitude)  # 移动到(-250,-100)位置
    tower.stamp()  # 一直显示出来
    tower.goto(0, tower_altitude)
    tower.stamp()
    tower.goto(tower_distance, tower_altitude)


if __name__ == "__main__":
    draw_towers()
    set_plate(1)

    plate = turtle.Turtle("plate_1")
    plate.forward(200)
    turtle.done()

B站博主所写代码参考网址:需要魔法(可参考网络代理文章)

#能可视化代码,但是turtle库的绘制方法不熟悉
import turtle

# ==============
#  常量设置
# ==============
N = 7  # 汉诺塔层数限制

BasePL = 12  # plate的大小基数,修改这个能够调整plate的大小
TowerP = 5  # Tower的线宽
TowerW = 110  # Tower的底座宽度
TowerH = 200  # Tower的高度
TowerSpace = 260  # Tower的之间的距离,从中心到中心
HORIZON = -100  # Tower的底座高度,用于定位
# 动画速度,5是比较适中的速度
PMS = 5

# 优化处理
Isjump = True

POLES = {
    "1": [],
    "2": [],
    "3": [],
}
PLATES = []  # 存储所有圆盘对象

# 塔的颜色
LineColor = "black"
# 多个盘子的颜色
FillColors = [
    "#d25b6a",
    "#d2835b",
    "#e5e234",
    "#83d05d",
    "#2862d2",
    "#35b1c0",
    "#5835c0"
]
# 建立窗体
SCR = turtle.Screen()
# SCR.tracer()
SCR.setup(800, 600)  # 设置窗体大小


# 设置圆盘形状
def set_plate(pi=0):
    _pi = pi + 2
    t = turtle.Turtle()
    t.hideturtle()
    t.speed(0)
    t.penup()
    t.begin_poly()
    t.left(90)
    t.forward(BasePL * _pi)
    t.circle(BasePL, 180)
    t.forward(BasePL * 2 * _pi)
    t.circle(BasePL, 180)
    t.forward(BasePL * _pi)
    t.end_poly()
    p = t.get_poly()
    pname = 'plate_%s' % pi
    SCR.register_shape(pname, p)


# 设置塔柱形状
def set_tower():
    t = turtle.Turtle()
    t.hideturtle()
    t.speed(0)
    t.penup()

    t.begin_poly()
    t.left(90)
    t.forward(TowerW)
    t.circle(-TowerP, 180)
    t.forward(TowerW)
    t.forward(TowerW)
    t.circle(-TowerP, 180)
    t.forward(TowerW - TowerP / 2)

    t.left(90)
    t.forward(TowerH)
    t.circle(-TowerP, 180)
    t.forward(TowerH)
    t.end_poly()
    p = t.get_poly()
    SCR.register_shape('tower', p)


# 绘制塔柱
def draw_towers():
    set_tower()
    for tx in [-TowerSpace, 0, TowerSpace]:
        t3 = turtle.Turtle('tower')
        t3.penup()
        t3.goto(tx, HORIZON)


# 绘制圆盘
def draw_plates(pn=4):
    plates = []
    for i in range(pn):
        set_plate(i)
        _plate = 'plate_%s' % i
        _p = turtle.Turtle(_plate)
        _colorIdx = i % len(FillColors)
        _color = FillColors[_colorIdx]

        _p.color(_color, _color)
        _p.speed(PMS)
        plates.append(_p)
    # 反序,大的在前,小的在后
    global PLATES
    PLATES = plates[:]


# 绘制移动过程
def draw_move(diskIndex, fromPindex, toPindex):
    p = PLATES[diskIndex - 1]
    index_loc = {
        "A": 1,
        "B": 2,
        "C": 3
    }
    toP = index_loc.get(toPindex, None)
    fromP = index_loc.get(fromPindex, None)

    p.penup()

    mx = (toP - 2) * TowerSpace
    my = HORIZON + len(POLES[str(toP)]) * BasePL * 2

    if fromP != None:
        POLES[str(fromP)].remove(p)
        if Isjump:
            px, py = p.pos()
            p.goto(px, TowerH + py)
            p.goto(mx, TowerH + py)

    p.goto(mx, my)
    POLES[str(toP)].append(p)


# 将所有圆盘移动到起点
def movetoA(n, fromPindex):
    for i in range(n, 0, -1):
        draw_move(i, None, fromPindex)


# 移动指定层圆盘diskIndex,从fromPole出发,到达toPole
def moveDisk(diskIndex, fromPole, toPole):
    """
    :param diskIndex: 圆盘的索引(从上往下,第一层为1,第二层为2、、、第n层为n)
    :param fromPole: 出发的柱子(起点)
    :param toPole: 要到达的柱子(终点)
    :return:
    """
    draw_move(diskIndex, fromPole, toPole)


# 核心函数,入口
def moveTower(height, fromPole, withPole, toPole):
    """
    :param height: 汉诺塔高度——层数
    :param fromPole: 出发的柱子(起点)
    :param withPole: 进过的柱子(中转点)
    :param toPole: 要到达的柱子(终点)
    :return:
    """
    if height == 1:
        # 基础情形:一层的汉诺塔
        moveDisk(1, fromPole, toPole)
        return

    # 先将圆盘1到n - 1看作一个整体从起点塔移动到中转塔(用目标塔作为本步骤的中转)
    moveTower(height - 1, fromPole, toPole, withPole)
    # 再将圆盘n从起点塔A移动到目标塔C
    moveDisk(height, fromPole, toPole)
    # 最后将圆盘1到n - 1看作一个整体从中转塔移动到目标塔(用起点塔作为本步骤的中转)
    moveTower(height - 1, withPole, fromPole, toPole)


if __name__ == '__main__':
    # 调用
    # 三层汉诺塔,A为出发柱子,B为中转柱子,C为目标柱子
    n = N

    SCR.tracer(0)
    draw_towers()
    draw_plates(n)
    movetoA(n, "A")
    SCR.tracer(1)

    # SCR.delay(3)

    moveTower(n, "A", "B", "C")
    turtle.done()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/556753.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库管理-第171期 Oracle是用这种方式确保读一致的(20240418)

数据库管理171期 2024-04-18 数据库管理-第171期 Oracle是用这种方式确保读一致的&#xff08;20240418&#xff09;1 基本概念2 用处3 注意事项总结 数据库管理-第171期 Oracle是用这种方式确保读一致的&#xff08;20240418&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#x…

Docker文档阅读笔记-How to Run GUI Based Applications inside Docker?

以后的文档阅读笔记不在一一介绍。以后只总结干货和重点。 Step 1 使用Systemctl命令启动docker服务&#xff1a; systemctl start docker // to start the docker service. systemctl status docker // to check the status . systemctl restart docke…

mybatis创建入门流程体验

mysql数据库中建表 drop table if exists tb_user;create table tb_user(id int primary key auto_increment,username varchar(20),password varchar(20),gender char(1),addr varchar(30) );INSERT INTO tb_user VALUES (1, zhangsan, 123, 男, 北京); INSERT INTO tb_user …

四川易点慧电子商务抖音小店:安全先行,购物无忧

随着互联网的飞速发展&#xff0c;电子商务已成为人们日常购物的重要渠道。抖音小店作为新兴的电商平台&#xff0c;凭借其独特的社交属性和庞大的用户基础&#xff0c;迅速崛起并吸引了众多商家的入驻。在这个背景下&#xff0c;四川易点慧电子商务有限公司&#xff08;以下简…

Android11应用安装未知来源的权限改动

最近开发的App需要下载安装另一个App。这就涉及到了app的安装代码。关于App的安装代码&#xff0c;写了不少&#xff0c;所以这一块觉得不是问题&#xff1a; 判断版本&#xff0c;Android8.0判断是否有未知来源安装全选&#xff0c;没有则打开未知来源安装权限设置界面去开启…

Linux并发程序设计(1):进程的创建和回收

目录 1、基本概念概念 1.1 程序 1.2 进程 1.3 进程的内容 1.4 进程类型 1.5 进程状态 2、常用命令 2.1 查看进程信息 2.2 改变进程优先级 2.2.1 按用户指定的优先级运行进程 2.2.2 改变正在运行进程的优先级 2.3 其他相关指令 3、进程的创建和结束 3.1 子进程创建 3.1.1 …

Odoo讨论+聊天模块:一体化内部协作平台,赋能高效沟通与业务流程协作

Odoo讨论聊天模块&#xff1a;一体化内部协作平台&#xff0c;赋能高效沟通与业务流程协作 Odoo 讨论模块是一个集成了即时通讯、文件共享、业务关联、权限控制等功能于一体的内部协作工具&#xff0c;允许用户通过跨模块的聊天窗口或通过专用的“讨论”面板互相发送消息、分享…

Golang(一):基础、数组、map、struct

目录 hello world 变量 常量&#xff0c;iota 函数 init函数和导包过程 指针 defer 数组和动态数组 固定长度数组 遍历数组 动态数组 len 和 cap 截取 切片的追加 map 四种声明方式 遍历map 删除 查看键是否存在 结构体 声明 作为形参 方法 封装 继承…

笔记软件功能多样的是哪款?做笔记的软件哪个好用

在快节奏的现代生活中&#xff0c;笔记软件已成为我们提高工作效率、记录生活点滴的重要工具。想象一下&#xff0c;在繁忙的工作中&#xff0c;你能够快速记录下关键信息&#xff0c;或在灵感迸发时及时捕捉&#xff0c;这是多么方便高效。 一款功能多样的笔记软件&#xff0…

Syncovery for Mac:高效文件备份和同步工具

Syncovery for Mac是一款专为Mac用户设计的文件备份和同步工具&#xff0c;凭借其高效、安全和易用的特点&#xff0c;深受用户好评。 Syncovery for Mac v10.14.2激活版下载 该软件具备强大的备份功能&#xff0c;支持多种备份方案和数据格式&#xff0c;用户可以根据需求轻松…

Python教学入门:函数

在 Python 中&#xff0c;def 关键字用于定义函数。函数是一段可重用的代码块&#xff0c;用于执行特定的任务或操作。通过定义函数&#xff0c;可以将一段代码封装起来&#xff0c;使其可以在程序中被多次调用&#xff0c;提高代码的复用性和可维护性。 下面是 def 函数定义的…

pandas/python 一个实战小案例

上次写坦克游戏的时候&#xff0c;接触了一点pandas&#xff0c;当时只是简单了解了一下如何遍历行和列并获取值来替换图片&#xff0c;想更多了解pandas。正好有一些数据需要筛选&#xff0c;试试能不能用通过代码实现。虽然总的来说不复杂&#xff0c;但由于原始数据在命名、…

如何训练猫出门不害怕:耐心做好这些训练,轻松get能溜的小猫

一般我们外出见到的都是遛狗的&#xff0c;溜猫的相对少见&#xff0c;一方面是因为猫咪是喜欢安静独处的小动物&#xff0c;另一方面是糟乱的环境也容易引起猫咪的应激。对于是否应该“溜猫”&#xff0c;有两个极端的阵营。一些铲屎官认为应尊重猫的天性&#xff0c;胆小不爱…

如何使用AI写作扩写文章?看完这篇学会扩写

如何使用AI写作扩写文章&#xff1f;在数字化时代的浪潮下&#xff0c;人工智能&#xff08;AI&#xff09;已经深入渗透到我们生活的各个领域&#xff0c;其中&#xff0c;AI写作扩写技术更是以其高效、便捷的特点受到了广大用户的青睐。它不仅极大提升了写作效率&#xff0c;…

Leetcode算法训练日记 | day29

一、递增子序列 1.题目 Leetcode&#xff1a;第 491 题 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&…

硬件?、嘉立创EDA画PCB规则设计

1、打开规则设计 设置单位为mil 点击全部 将安全距离设置为8mil&#xff0c;这个8mil是目前很多生产PCB的工厂可以做的&#xff0c;如果距离设置的更小也就是性能要求更高&#xff0c;相应的生产成本也高元件到元件的距离设置为20mil 2、设置导线的宽度规则&#xff0c;可以对v…

第G6周:CycleGAN实践

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、CycleGAN原理 &#xff08;一&#xff09;CycleGAN的原理结构&#xff1a; CycleGAN&#xff08;循环生成对抗网络&#xff09;是一种生成对抗网络&…

思维导图软件Xmind for Mac 中文激活版 支持M

XMind是一款非常受欢迎的思维导图软件&#xff0c;它应用了Eclipse RCP软件架构&#xff0c;注重易用性、高效性和稳定性&#xff0c;致力于帮助用户提高生产率。 Xmind for Mac 中文激活版下载 XMind的程序主体由一组插件构成&#xff0c;包括一个核心主程序插件、一组Eclipse…

文件后缀变成.halo? 如何恢复重要数据

.halo 勒索病毒是什么&#xff1f; .halo勒索病毒是一种恶意软件&#xff0c;属于勒索软件&#xff08;Ransomware&#xff09;的一种。这种病毒会加密用户计算机上的文件&#xff0c;并要求受害者支付赎金才能获取解密密钥&#xff0c;从而恢复被加密的文件。勒索软件通常会通…

力扣(leetcode) 42. 接雨水 (带你逐步思考)

力扣(leetcode) 42. 接雨水 &#xff08;带你逐步思考&#xff09; 链接&#xff1a;https://leetcode.cn/problems/trapping-rain-water/ 难度&#xff1a;hard 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多…
最新文章