递归视角下

2023-11-07

def listSum(numbers):
    if not numbers:
        return 0
    else:
        (f, rest) = numbers
    return f + listSum(rest)

myList = (1, (2, (3, (4,None))))
total = listSum(myList)
print(total)

while循环何时退出? 恐怕是while循环技巧所在,即选择恰当的变量作为退出循环的条件判断。

下面的栗子选择了哪个变量作为退出条件?

原题来自宁波第23届中小学信息比赛小学组决赛最后一道题。尝试用python代替原题要求的pascal count.pas/exe)

alt

问题描述: 小Q的编程技术在一次搭积木比赛中也成了秘密武器。原来,比赛的规则是这样的:给你N个小木块(全部为一样大小的正方体)。快速搭成如下图规则的形状(下图为5层的规模),要求层数为最大限度。

由于小Q编了个程序,只要输入小木块的个数N,就可以马上求出最多可以搭几层,还剩几个,所以小Q每次都是一次成功,从不需要翻工,速度也就领先了,你会编小Q这样的程序吗?

【输入数据】

输入文件count.in:文件中只有一个整数N,表示小木块的个数,已知1≤N≤2^31。

【输出数据】

输出文件count.out:文件中有两行整数,第一行是最多可以堆的层数,第二行是剩余的小木块

Python语言的搭积木的诀窍 解法仅供参考

图片

递归的妙处:

第一条:每次递归都能将问题规模缩减下来。

第二条:对应递归终止条件,递归必须有个出口,不然会陷入无限递归当中。

第三条:将递归问题细分为更小的递归问题,然后再进行递归调用。

首先,只需要找到相邻两层之间数量关系,较大层数和小木块数量之间的关系表达为为consumer()函数

请看图:第1层是1,第2层是3,第3层用掉的木块是x,那么前3层用掉的木块总数是前2层用掉的总数,再加上第3层的木块数量。

留意:前3层和第3层所指不同,显然前3层包含第3层。持续倒推,就可以建立起第n层和第1层之间的数量关系。

alt

第n-1层需要多少个小木块作为输入参数,

x = consumer(n-1)

推出第n层需要多少小木块,

consumer(n)=consumer(n-1) + 0.5*(n**2+n)

为啥是第2层开始,总能表达为

consumer(n-1) + 0.5*(n**2+n)

为何1-> n 层的cube总的数量 = 第 n-1 层数量 + 0.5*(n**2+n)

符合以上数学关系的理由是第 n 层木块数量与 n 存在关系,不妨从求解三角形的面积公式得到灵感:

1+2+3+....n = 0.5*(n**2+n)

alt

第n层的平面图计算高斯数

please enter the cube numeber:20
4, 0

please enter the cube numeber:100
7, 16.0

please enter the cube numeber:1000
17, 31.0

但python递归的问题爆栈在随手将 n 大到离谱时如约而至!呵呵

please enter the cube numeber:10000000000000

...
RecursionError: maximum recursion depth exceeded in comparison

那么,这时候有两个办法:

1、设法取消递归栈的上限:996 次; 2、或者改用循环的递推实现;

如何理解递归和循环?

SOLID原则:

分离出子函数layerSum(n)计算第 n 层有多少cube;

主函数 consumeWhile(total)判断累积cube超过total为退出循环的条件判断;

*可以与递归写法的结果比较是否一致

# SOLID分离原则 
def layersSum(n):
    # 第 n 层有多少cube
    return 0.5 *(n**2 + n)

上述可以灵活修改每一层的几何形状,如改为正方形等等;

def consumeWhile(total):
    # 表达相邻两层之间的数量关系
    # cur,upper = layers(1),layers(2)
    # upper变量是从 1-n 层共有多少cube
    cur,layer = 0,0
    while cur <= total:
        cur += layersSum(layer)
        if cur == total:
            return layer,0
        elif cur > total:
            return layer-1,total - (cur-layersSum(layer))
        layer += 1
        
        
total = 100000000
print(consumeWhile(total))

(842, 153956.0)

递归的写法优雅而有趣,但实际项目工程中并不是首选。正如在while循环中看到当 total 数字很大时,递归的不仅运算花费的时间多且易溢出而报错。

这时循环的写法系统的开销更少。

本文由 mdnice 多平台发布

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

递归视角下 的相关文章

  • 关于 Error: Cannot find module ‘webpack/lib/RuleSet‘ 的详细解决方法(亲测有效)- 以及删除脚手架的方法

    对于出现的这个错误 之前我也尝试了网上的多种解决方案 最终经过测试后 是通过将原来的 vue cli 版本降级到 4 5 15 版本 最后再重新安装 node modules 包 才得以解决 下面是我将介绍怎么安装 4 5 15 版本的脚手
  • linux svn 用户名存储,Linux下SVN账户密码保存设置

    Linux下用SVN进行更新等操作时 总是提示输入用户名和密码 很不方便 因此搜了下解决办法 总结如下 Linux下用SVN进行更新等操作时 总是提示输入用户名和密码 很不方便 因此搜了下解决办法 总结如下 打开SVN配置文件 vim ho
  • SQL注入(2)——各种注入

    本专栏是笔者的网络安全学习笔记 一面分享 同时作为笔记 前文链接 WAMP DVWA sqli labs 搭建 burpsuite工具抓包及Intruder暴力破解的使用 目录扫描 请求重发 漏洞扫描等工具的使用 网站信息收集及nmap的下
  • 亲密关系沟通-【独特性】尊重与探索他人

    忽视自己是逃避 忽视对方也是逃避 故事 理发师抱怨老婆不换空调 你有没有问过她 为什么不愿意换 谁知道她怎么想的 你承认对方的独特性 就不用做任何改变 叙述测试 你讲述经历里的别人有ta的想法吗 如何把对方从一个活生生的人变成ta就是那样的

随机推荐

  • HTTPS为什么安全 &分析 HTTPS 连接建立全过程

    本文将分两个专题去理解HTTPS 专题一 HTTPS为什么安全 1 http为什么不安全 http协议属于明文传输协议 交互过程以及数据传输都没有进行加密 通信双方也没有进行任何认证 通信过程非常容易遭遇劫持 监听 篡改 严重情况下 会造成
  • WSL无法保存文件(权限不足)

    sudo chown R username 其中username是你的用户名
  • windows vscode 安装+配置go环境

    一下载 go语言官方下载地址 https golang org dl 找到适合你系统的版本下载 本人下载的是windows版本 也可以下载Source自己更深层次研究go语言 二安装 一路next 三 安装后目录 Go语言安装之后 C Go
  • WebApi 打个Attribute 统一处理异常

    我们处理异常的时候通常都要写形如以下的代码 try xxxxx catch Exception ex log write ex Message 前一段时间看杨中科的视频 其中吐糟了 mvc 的管道机制 当然用在web ui 的渲染上这个还不
  • Buck电路基础知识

    版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本文链接 https blog csdn net weixin 42005993 article details 120144144 这
  • Windows下libmodbus库的编译和使用

    一 前言 最近要搞一个PC端Qt上位机控制机械手的移动 需要用到串口io卡 控制的话需要使用libmodbus库 就想着自己编译一下libmodbus库 过程如下 二 编译过程 2 1 libmodbus的下载和安装 下载地址 https
  • pytorch7-可视化训练过程(过程中显示)

    import torch import torch nn as nn import torchvision import torchvision utils as vutils from torch optim import SGD imp
  • 安全连载——CSDN区块链大本营出品

    史上杀伤力最大的溢出型漏洞到底是什么 看这一篇就够了 第1期 4月发生的BEC事件以及SMT事件已经沉淀一段时间了 具体的情况也被多方媒体所报道 相关的漏洞根源问题也有很多大神团队的分析和指正 近日 有安全团队将各种已经发生或可能发生的类似
  • Marshaller和Unmarshaller用法示例

    import java io FileNotFoundException import java io FileOutputStream import java io OutputStream import javax xml bind J
  • Qt之QDialog禁用右上角关闭按钮

    setWindowFlags windowFlags Qt WindowCloseButtonHint
  • 【深度学习】笔记12:win10下的VS2013编辑代码的时候,非常卡顿,怎么样解决?

    给新电脑连续配置了三天环境 双系统下的caffe和NVIDIA环境配置好之后 终于可以看代码了 结果在vs2013下对代码进行注释的时候 代码编辑器用起来非常卡顿 这个问题的解决方法如下所示 1 首先确定是不是硬件和系统的问题 据说win8
  • 2.4.1 C# 和 F# 中的类型推断

    2 4 1 C 和 F 中的类型推断 大多数的类型有简称 例如 int 或 Random 只有很少一部分需要类型推断 因为手写类型名称并不困难 C 2 0 支持泛型 因此 可以构造更复杂的类型 在函数语言中的类型 像 F 是相当复杂的 尤其
  • R语言legend函数参数详解

    legend x y NULL legend fill NULL col par col border black lty lwd pch angle 45 density NULL bty o bg par bg box lwd par
  • Scala学习系列(二)——环境安装配置

    Scala下载地址 https www scala lang org download 一 安装JDK 首先 因为Scala是运行在JVM平台上的 所以安装Scala之前要安装JDK 二 二进制安装方式 我们可以直接用二进制安装Scala
  • 合并BPL包图文教程

    Delphi IDE 本身就是一个插件模式的工具 插件的好处不用多说 运行包的BPL 其实就是众多单元的集合 因此可以再次重新组合 只要你将各个BPL包用到的单元再组合一次 本文以 http code google com p tangra
  • libuv源码分析(1)事件循环分析

    前言 libuv总是报出一些让人难以理解的错误 作为一个C的项目 不具有Java JavaScript php那样的人气 很难百度到一些问题的答案 甚至google也不行 为了用好libuv 也为了学习吧 我开始看libuv的源码 不知道自
  • 【正点原子STM32连载】 第三十一章 睡眠模式实验 摘自【正点原子】APM32F407最小系统板使用指南

    1 实验平台 正点原子stm32f103战舰开发板V4 2 平台购买地址 https detail tmall com item htm id 609294757420 3 全套实验源码 手册 视频下载地址 http www openedv
  • 《机器学习》周志华(西瓜书)学习笔记 第二章 模型评估与选择

    机器学习 周志华 学习笔记 总目录 世上只有一种投资是只赚不赔的 那就是学习 当你的的能力还驾驭不了你的目标时 就应该沉下心来历练 当你的才华撑不起你的野心时 就应该静下心来学习 第二章 模型评估与选择 2 1 经验误差与过拟合 错误率 E
  • 11 【标准库之JSON对象 JSON5】

    13 JSON 对象 13 1 JSON 格式 JSON 格式 JavaScript Object Notation 的缩写 是一种用于数据交换的文本格式 2001年由 Douglas Crockford 提出 目的是取代繁琐笨重的 XML
  • 递归视角下

    def listSum numbers if not numbers return 0 else f rest numbers return f listSum rest myList 1 2 3 4 None total listSum