【算法】递归

递归

  • 递归
    • 初始递归:数列求和
    • 递归的应用:任意进制转换
    • 递归深度限制
    • 递归可视化:分形树
    • 递归可视化:谢尔宾斯基Sierpinski三角形
    • 递归的应用:汉诺塔
    • 递归的应用:探索迷宫
  • 分治策略和递归
  • 优化问题
    • 兑换最少个数硬币问题
  • 贪心策略

递归

递归是一种解决问题的方法,其精髓在于将问题分解为规模更小的相同问题,持续分解,直到问题规模小到可以用飞常简单直接的方式来解决。
递归的问题分解方式非常独特,其算法方面的明显特征就是:在算法流程中调用自身。
递归为我们提供了一种对复杂问题的优雅解决方案。

函数自己调用自己,形如:

int f(int x){
	xxxxx
	xxxxx
	xxxxx
	return f(x-1);
}

初始递归:数列求和

问题:给定一个列表,返回所有数的和
列表中数的个数不定,需要一个循环和一个累加变量来迭代求和

既不能用for,也不能用while,对不确定长度的列表求和

def listsum(numList):
	theSum=0
	for i in numList:
		theSum=theSum+i
	return theSum

print(listsum([1,3,5,7,9]))

求和实际上由一次次的加法实现,而加法恰有2个操作数

将问题规模较大的列表求和,分解为规模较小而且固定的2个数求和

数列求和问题首先具备了基本结束条件:当

递归的应用:任意进制转换

整数转换为任意进制
十进制有10个不同符号:convString=“0123456789”
比10小的整数转换成十进制,直接查表:convString[n]
比10大的整数,拆成一系列比10小的整数,逐个查表,如769,拆成7、6、9
递归三定律里,基本结束条件为:小于10的整数;拆解整数的过程就是向“基本结束条件”演进的过程
用整数除,和求余数两个计算将整数一步步拆开
除以“进制基base”://base
对“进制基”求余数:%base
问题分解为:余数总小于“进制基base”,是基本结束条件,可直接进行查表转换
整数商成为“更小规模”问题,通过递归调用自身解决

def toStr(n,base):
	convertString="0123456789ABCDEF"
	if n<base:
		return convertString[n]
	else:
	return toStr(n//base,base)+convertString[n%base]

print(toStr(1453,16))

当一个函数被调用的时候,系统会把调用时的现场数据压入到系统调用栈
每次调用,压入栈的现场数据称为栈帧
当函数返回时,要从调用栈的栈顶取得返回地址,恢复现场,弹出栈帧,按地址返回

递归深度限制

RecursionError
检查是否忘记设置基本结束条件,导致无限递归。
或者向基本结束条件演进太慢,导致递归层数太多,调用栈溢出

def tell_story():

在Python内置的sys模块可以获取和调整最大递归深度

递归可视化:分形树

Python的海龟作图系统tuetle moudle

import turtle
t=turtle.Turtle()
# 作图开始
for i in range(4):
	t

螺旋

import turtle

t=turtle.Turtle()

def drawSpiral(t,lineLen):
	if lineLen

分形:一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状,即具有自相似的性质

递归可视化:谢尔宾斯基Sierpinski三角形

面积趋于0,周长趋于∞
谢尔宾斯基三角形是由三个尺寸减半的谢尔宾斯基三角形按照品字形拼叠而成
我们无法真正做出谢尔宾斯基三角形,只能做出degree有限的近似图形
在degree有限的情况下,degree=n的三角形,由3个degree=n-1的三角形按品字形拼叠而成,边长均为degree=n的三角形的一半(规模减小)
当degree=0,则就是一个等边三角形,这是递归结束的基本条件

import turtle
def sierpinski(degree,points):
	colormap=['blue','red','green','white','yellow']

递归的应用:汉诺塔

规则:
一次只能移动一个
大盘子不能叠在小盘子上

假设有5个盘子串在1#柱上,需要移到3#柱上

  1. 把上面的一摞4个盘子移到2#柱上
  2. 把剩下的最大号盘子移到3#柱上
  3. 把2#柱上的4个盘子移到3#柱上

在这里插入图片描述
如果能有办法把最上面的4个盘子移到2#柱,那么问题就好解决了。接下来的问题就是把4个盘子从1#移到2#,此时问题规模已经减小:

  1. 把上面的一摞3个盘子移到3#柱上
  2. 把剩下的最大号盘子移到2#柱上
  3. 把3#柱上的3个盘子移到2#柱上

移动3个盘子可以分解为上面2个和下面的最大号盘子
移动2个盘子可以分解为上面的盘子和下面的盘子

思路:一定有三个柱子,两个柱子是无法完成的
将盘子从开始柱,经由中间柱,移到目标柱:

  1. 将上层N-1个盘子的塔,从开始柱,借助目标柱,移到中间柱;
  2. 将最大的(第N个)盘子从开始柱移到目标柱;
  3. 将放置在中间柱的N-1个盘子借助开始柱,移到目标柱

基本结束条件(最小规模问题):1个盘子的移动问题

def moveTower(height,fromPole,withPole,toPole):
    if height>=1:
        moveTower(height-1,fromPole,toPole,withPole)
        moveDisk(height,fromPole,toPole)
        moveTower(height-1,withPole,fromPole,toPole)
def moveTower(height,fromPole,withPole,toPole):
    if height>=1:
        moveTower(height-1,fromPole,toPole,withPole)
        moveDisk(height,fromPole,toPole)
        moveTower(height-1,withPole,fromPole,toPole)

def moveDisk(disk,fromPole,toPole):
    print(f"Moving disk[{disk}] from {fromPole} to {toPole}")

moveTower(3,"#1","#2","#3")

递归的应用:探索迷宫

将海归放在迷宫中间,找到出口

  1. 将整个迷宫的空间(矩形)分为行列整齐的方格,区分出墙壁和通道。每个方格具有行列位置,并赋予“墙壁”、“通道”的属性
  2. 考虑用矩阵方式来实现迷宫数据结构。采用“数据项为字符列表的列表”这两种列表的方式来保存方格内容。采用不同字符分别代表“墙壁+”、“通道 ”、“海归投放点S”,从一个文本文件读入迷宫数据
class Maze:
    def __init__(self,mazeFileName):
        rowsInMaze=0
        columnsInMaze=0
        self.mazelist=[]
        mazeFile=open(mazeFileName,'r')
        rowsInMaze=0
        for line in mazeFile:
            rowList=[]
            col=0
            for ch in line[:-1]:
                rowList append(ch)
                if ch=='S':
                    self.startRow=rowsInMaze
                    self.startCol=col
                col=col+1
            rowsInMaze=rowsInMaze+1
            self.mazelist.append(rowList)
            columnsInMaze=len(rowList)

探索迷宫的递归算法思路如下:

  1. 将海龟

所以需要有个机制记录海龟走过的路径:
沿途洒“面包屑”

递归调用的基本结束条件

def carpet(N,C):
    def check(n,x,y):
        if n<=1:
            return True
        n2=n//3
        if n2<=x<n2*2 and n2<=y<n2*2:
            return False
        return check(n2,x%n2,y%n2)

    for y in range(N):
        for x in range(N):
            if check(N,x,y):
                print(C,end='')
            else:
                print(' '*len(C),end='')
            print('')
#test
carpet(27,'[]')

分治策略和递归

将问题分为若干更小规模的部分
通过解决每一个小规模部分问题,并将结果汇总得到原问题的解
递归三定律:
基本结束条件,解决最小规模问题
缩小规模,向基本结束条件演进
调用自身来解决已缩小规模的相同问题
❖体现了分治策略
问题解决依赖于若干缩小了规模的问题
汇总得到原问题的解
❖应用相当广泛
排序、查找、遍历、求值等等

优化问题

计算机科学中许多算法都是为了找到某些
问题的最优解
例如,两个点之间的最短路径;
能最好匹配一系列点的直线;
或者满足一定条件的最小集合

兑换最少个数硬币问题

假设你为一家自动售货机厂家编程序,自动售货
机要每次找给顾客最少数量硬币;
假设某次顾客投进$1纸币,买了ȼ37的东西,要
找ȼ63,那么最少数量就是:2个quarter(ȼ25)
、1个dime(ȼ10)和3个penny(ȼ1),一共6个

贪心策略

一般我们这么做:
从最大面值的硬币开始,用尽量多的数量
有余额的,再到下一最大面值的硬币,还用尽量
多的数量,一直到penny(ȼ1)为止
因为我们每次都试图解决问题的尽量大的一部分
对应到兑换硬币问题,就是每次以最多数量的最
大面值硬币来迅速减少找零面值
❖“贪心策略”解决找零兑换问题,在美元
或其他货币的硬币体系下表现尚好

❖动态规划算法采用了一种更有条理的方式
来得到问题的解
❖找零兑换的动态规划算法从最简单的“1
分钱找零”的最优解开始,逐步递加上去
,直到我们需要的找零钱数
❖在找零递加的过程中,设法保持每一分钱
的递加都是最优解,一直加到求解找零钱
数,自然得到最优解

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

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

相关文章

蓝桥杯回文日期判断

思想&#xff1a;对于回文数的判断方法&#xff0c;最快的就是取其中一半的字符串长度&#xff0c;为s&#xff0c;然后将其进行翻转为s’ &#xff0c;再把两者进行拼接即可保证是回文数&#xff0c;这样子就解决了枚举所有回文数的问题。 注意点&#xff1a; 要求必须是有效…

机器学习:holdout法(Python)

import pandas as pd import numpy as np from sklearn.preprocessing import LabelEncoder, StandardScaler # 类别标签编码&#xff0c;标准化处理 from sklearn.decomposition import PCA # 主成分分析 import matplotlib.pyplot as plt from sklearn.model_selection impor…

积分梳状滤波器CIC原理与实现

CIC&#xff08;Cascade Intergrator Comb&#xff09;&#xff1a;级联积分梳状滤波器&#xff0c;是由积分器和梳状滤波器级联而得。滤波器系数为1&#xff0c;无需对系数进行存储&#xff0c;只有加法器、积分器和寄存器&#xff0c;资源消耗少&#xff0c;运算速率高&#…

docker部署项目,/var/lib/docker/overlay2目录满了如何清理?

docker部署项目&#xff0c;/var/lib/docker/overlay2目录满了如何清理&#xff1f; 一、问题二、解决1、查看 /var/lib/docker 目录&#xff08;1&#xff09;、containers 目录&#xff08;2&#xff09;、volumes 目录&#xff08;3&#xff09;、overlay2 目录 2、清理&…

【高并发内存池】定长内存池实现

目录 一、项目介绍 二、内存池介绍 2.1、池化技术 2.2、内存池 2.3、内存池主要解决的问题 三、malloc了解 四、设计定长内存池 五、和new(实际malloc)对比性能测试 一、项目介绍 当前项目实现的高并发内存池原型是goole的开源项目tcmalloc&#xff0c;tcmalloc全称为T…

Qt —— 编译Qt5版本QFTP库,并实现连接服务、获取列表、上传、下载、删除文件等操作(附源码、附基于Qt5编译好的QFTP库)

示例效果1 示例效果2 介绍 QFTP是Qt4的库,Qt5改用了QNetworkAccessManager来代替。但是Qt5提供的QNetworkAccessManager仅支持FTP的上传和下载,所以只能将QFTP库编译为Qt5的库来进行调用。 QFTP在Github的下载地址:https://github.com/qt/qtftp 客户端源码生成的release结果…

739.每日温度 496.下一个更大元素 I

739.每日温度 496.下一个更大元素 I 739.每日温度 力扣题目链接(opens new window) 请根据每日 气温 列表&#xff0c;重新生成一个列表。对应位置的输出为&#xff1a;要想观测到更高的气温&#xff0c;至少需要等待的天数。如果气温在这之后都不会升高&#xff0c;请在该位…

MSVS C# Matlab的混合编程系列1 - 看似简单的问题引出

前言&#xff1a; 问题提出&#xff0c;如何把Matlab(本文简称MT)的算法集成到Visual Studio(本文简称VS)里面运行&#xff1f; 本文&#xff0c;通过编制一个MT中最简单的加法函数&#xff0c;我们把他做成 MSVS C#能够使用的动态库&#xff0c;说明了MSVS C# 和 MT集成的最…

Adobe全新AI驱动的Premiere Pro功能消除了枯燥的音频编辑任务

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

亚信安慧AntDB数据库:开辟数据库新纪元

在数字化时代的快速发展中&#xff0c;数据成为企业的核心资产&#xff0c;而数据库则是管理和利用这些数据的关键。 为满足企业日益复杂的混合负载场景和混合数据类型业务需求&#xff0c;亚信科技AntDB提出了全新的“超融合”理念。该理念将多引擎、多能力融合在一起&#x…

Docker(二)安装指南:主要介绍在 Linux 、Windows 10 和 macOS 上的安装

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 安装 Docker Docker 分为 stable test 和 nightly 三个更新频道。 官方网站上有各种环境下的 安装指南&#xff0c;这里主要介绍 Docker 在…

Java进阶-Tomcat发布JavaWeb项目

对于云服务器&#xff0c;程序员一般不会陌生&#xff0c;如果项目需要发布到现网&#xff0c;那么服务器是必不可缺的一项硬性条件&#xff0c;那么如何在云服务器上部署一个项目&#xff0c;需要做哪些配置准备&#xff0c;下面就由本文档为大家讲解&#xff0c;本篇以Tomcat…

windows vscode jsoncpp cmake c++ 构建项目

jsoncpp的编译和使用推荐文章&#xff1a;jsoncpp的编译和使用 | 爱编程的大丙 (subingwen.cn)https://www.subingwen.cn/cpp/jsoncpp/从这个链接下载jsoncpp-master&#xff1a;https://github.com/open-source-parsers/jsoncpp 可以把这个文件夹名字改成jsoncpp&#xff0c;…

街机模拟游戏逆向工程(HACKROM)教程:[10]68K汇编add指令

我们之前已经介绍了move指令&#xff0c;从本章开始&#xff0c;我们会一步步介绍更多的M68K指令。 简介&#xff1a; add :加法指令 该指令的作用是[源操作数]加[目的操作数]&#xff0c;结果传递至[目的操作数]&#xff0c;[源操作数]保持不变。 例子&#xff1a;…

MySQL复合查询 内外连接

目录 前言&#xff1a; 多表查询&#xff1a; 显示部门号为10的部门名&#xff0c;员工名和工资 : 显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别: 自连接 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号&#xff09; 子查询 单行子查询&#…

汽车微电机行业研究:预计2029年将达到188亿美元

微电机行业是技术密集型行业&#xff0c;其起源于欧洲的德国、瑞士等国家&#xff0c;发展于日本。随着改革开放&#xff0c;中国作为发展中国家&#xff0c;承接了德国、日本等发达国家的汽车微电机产业转移&#xff0c;技术扩散逐步向我国转移。 微特电机广泛应用于信息处理设…

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?

ctypes库介绍 ctypes是Python的一个外部库,它提供了一种灵活的方式来调用C语言的动态链接库(DLL)或共享库(SO)。通过ctypes,我们可以在Python中直接调用C语言编写的函数和变量,从而实现跨语言的互操作。 ctypes 它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的…

数学建模美赛资料(赛题+获奖论文更新)

数学建模美赛历年真题可以帮助我们了解比赛的出题思路&#xff0c;对建模比赛有一个大致的了解。 在备赛过程中&#xff0c;通过往年真题&#xff0c;我们可以了解考试的范围和重点&#xff0c;做到心中有数&#xff0c;可以有的放矢。通过真题&#xff0c;我们可以感受到各个…

Java 方法(方法的调用机制、方法的传参机制)

方法 方法就是将一个功能抽取出来&#xff0c;把代码单独定义在一个大括号内&#xff0c;形成一个单独的功能。 当需要这个功能的时候&#xff0c;就可以去调用。这样即实现了代码的复用性&#xff0c;也解决了代码冗余的现象。 修饰符 返回值类型 方法名 &#xff08;参数列…

CC工具箱使用指南:【计算面积】

一、简介 在Arcgis中&#xff0c;如果要计算面要素的面积&#xff0c;有几种方法。 1、gdb数据会自带一个shape_area字段&#xff0c;这就是面的平面面积&#xff0c;单位是平方米&#xff1a; 2、在双精度字段上右键单击&#xff0c;在弹出的菜单中点击【计算几何】&#xf…