递归

递归(走楼梯,阶乘)

隐身守侯 提交于 2020-03-17 03:51:21
递归我记得,我最先接触的递归的例子是汉诺塔。 但是本文现在不讲汉诺塔,嘿嘿! 我们从简单的开始 递归现象发生于递归函数,递归函数是直接或者间接的调用自己本身的这么一种函数。 举个例子 求从1连成乘到n的积,也就是求 n! 。其中就是重复的去用一个数乘一个数,接着再乘一个数,一直乘到100;我们用递归完成, public int recursion ( int i , int n ) { if ( i == n ) return n ; return i * recursion ( i + 1 ) ; } 函数recursion自己调用自己,这就是递归现象。 递归是一种很棒的算法思想,你只需要找到复杂问题中最小的重复单元或者说可能性单元,然后复杂的细节就交给计算机吧! 例子二,说有一个n级的台阶,每一步有两种走法,每次跨一步或者跨两步,问从第一阶开始,走到最后一阶有几种不同的走法。 我们知道,每一次向前都有两种走法,一阶或者两阶。问走到最后一阶有多少种走法,走到最后一阶就是说每次一步或者两步的一种组合只要能走到最后一阶,就算一种成功的组合。 每一步两种可能性,有n个台阶。问题是复杂的,但是其中最小的重复单元很明显,就是每次所面临的两种可能性,最后需要满足组合步数等于台阶数就行。 int ans = 0 ; //定义一个全局变量 记录符合要求的组合数 public void

函数递归+匿名函数+内置函数day15

感情迁移 提交于 2020-03-16 06:26:52
一、函数递归 什么是函数递归:   函数递归调用是一种特殊的嵌套调用,在调用一个函数的过程中,又直接或间接地调用了该函数本身。 其中,函数的递归有明确的结束条件,不能无限制的调用,否则会撑破内存,在Python中限定递归最多调用1000层。 1000层这个值是大概的数值,这个数值可以通过Python内置的功能进行更改。 递归必须要有两个明确的阶段:   递推:一层层递归调用下去,强调每次进入下一次递归,问题规模都在减小   回溯:递归必须要有一个明确的结束条件,在满足该条件时结束递推,开始一层层回溯   其中,递归的精髓在于通过不断的重复逼近一个最终结果。 循环(while)能做的,递归都可以,为什么还要递归?   因为相较于循环,递归无须确定循环次数,只需确定结束条件。 举个例子,递归的应用: 二分法: 有个从小到大排列对的列表,判断某个值是否在里面。 nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,312] def search(search_num,nums): print(nums) if len(nums)==0: print('not exists') return mid_index=len(nums)//2 if search_num>nums[mid_index]: nums=nums[mid_index+1:]

循环或递归的选择

不问归期 提交于 2020-03-15 23:40:10
循环就不多介绍了,简单说一下递归。程序中,递归一般是指方法(函数)调用自己。常用的递归类型有两种: 头递归 (head recursion) 是在接近方法开始处发起的递归调用。头递归是要处理的第一批内容之一,因为它调用自己,所以它依赖于调用堆栈上执行的上一次操作的结果。因为它使用调用堆栈来处理,所以如果调用堆栈不够大,则有可能发生堆栈溢出。 尾递归 (tail recursion) 是在结尾处执行的递归调用,是要处理的最后一行代码。无论递归调用有多深,此方法都不会使用调用堆栈。 我们平时所说的递归一般为头递归。 为了更清晰的理解概念,通过代码分析一下,分别使用头递归、尾递归、循环的方式实现阶乘方法,下面以5!(5 的阶乘)为例做计算。 1)头递归 public long getFactorial(long currNum) { if (currNum == 1) { return 1; } return currNum * getFactorial(currNum - 1); } 每个递归调用需要完成并放在递归堆栈上,才能计算阶乘,以表格表示栈,表格的每一行就是压到栈里的内容。 1 * 1 当currNum=1时,栈达到最大,此时,开始由栈顶层逐级出栈运算,计算顺序: 1 * 1 = 1 * 2 = 2 * 3 = 6 * 4 = 24 * 5 = 120 2 * f(1) 3 *

python-递归函数

蹲街弑〆低调 提交于 2020-03-15 23:20:32
#recursion_function.py #-*- coding:utf-8 -*- def recursion(x): if x == 1: return 1 return x * recursion(x - 1) f1 = recursion(1) f2 = recursion(2) f3 = recursion(3) f4 = recursion(4) print f1, f2, f3, f4 递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。 解决递归调用栈溢出的方法是通过 尾递归 优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。 尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。 上面的 fact(n) 函数由于 return n * fact(n - 1) 引入了乘法表达式,所以就不是尾递归了

Tail Recursion尾递归

为君一笑 提交于 2020-03-15 22:38:00
什么是尾递归 Tail Recursion /teɪl rɪˈkɜːrʒn/ In traditional recursion , the typical model is that you perform your recursive calls first, and then you take the return value of the recursive call and calculate the result. In this manner, you don't get the result of your calculation until you have returned from every recursive call. In tail recursion , you perform your calculations first, and then you execute the recursive call, passing the results of your current step to the next recursive step. This results in the last statement being in the form of ( return (recursive-function params) ). Basically,

[置顶]
读入优化&输出优化

流过昼夜 提交于 2020-03-15 19:43:35
注意了注意了注意了,重要的事情说3遍,这个东西是骗分神器,骗分神器,骗分神器!!! 众所周知:scanf比cin快得多,printf比cout快得多,如果你不知道就……就现在知道了 那有没有更快的呢?当然。 请看: 我懵逼了,至于慢近100ms吗? 好吧,这就是读入优化的效果,在数据很恐怖的情况下能比scanf多过1-5个点…… 比如说这种: 都说了要读入优化你还不读入优化,那不是找死吗…… 前面都是废话,现在开始说正事 读入优化 首先,读入优化这里是只是针对整数,getchar读字符是非常快的,所以我们就用getchar了。(下面都假设输入的数为x) 负数处理 很简单,用一个标志变量f,开始时为1,当读入了’-’时,f变为-1,最后 x*=f 即可 绝对值部分处理 显然getchar每次只能读一位,所以,每当读了一位时x*=10,为这一位“留位置”。 举个例子:现在读入了123,x为123,再读入了一个4,x*=10,变为了1230,现在它的最后一位空出来了,正好留给4,x+=4,x就变为了1234,当然,这里的’4’是char类型,需要减去’0’才是4,即: x=x*10+s-'0' (s为当前输入的字符) 关于细节 很多时候是有多余空格或者其他的乱码字符输入,为了防止bug,我们要严谨~详见代码。 代码 void read(int &x)//'&'表示引用

递归查找的问题

陌路散爱 提交于 2020-03-15 17:10:39
背景 前几天在开发过程中遇到一个需求,前端需要动态渲染一个菜单,这个菜单是一个树状结构,就是每个菜单中可能有多个子菜单,子菜单中又有子菜单,同时呢,每个菜单都可以单独绑定一个页面。为了加速前端加载页面和渲染速度,后端一次性将整个菜单和页面信息用树形结构返回给前端,结构大概如下(主菜单不算在后端返回的数据中,只是前端的一个入口,黄色虚线框中的数据才是真正需要的): 转化为树结构: 后端将如上数据结构返回给了前端,前端需要将其加载为树型结构。 同时另一个需求是点击某个菜单,如果有页面那么就直接展示其对应的第一个也没,如果没有需要继续找子菜单的第一个页面,都没有那就不显示页面。 按照上图所展示的数据,那么,如果点击 主菜单 ,那么需要战士 页面1-1-1-P1 ,也就是红色展示的部分;如果点击 菜单2 那么需要展示 页面2-P1 ,也就是绿色展示的部分。 实现 需求有了,数据也有了,那么我们考虑实现方式。 首先这个是树,如果加上主目录的话,算是1棵有多个节点的数;如果不算主目录那么算是多棵树。 不管是1棵树,还是多棵树的方式考虑,都是采用 广度优先遍历 的,这里呢我们按照多棵树遍历的方式使用js实现了一下: function getFirstPage(list) { for (const item of list) { if (item.pages && item.pages

Leetcode周赛-180场周赛20200315

眉间皱痕 提交于 2020-03-15 12:32:28
本周周赛的结果: 最后一题一直报溢出的错误,就懒得管了呜呜呜 1. 矩阵中的幸运数 题目描述: 我的做法: 暴力法-遍历 2.设计一个支持增量操作的栈 题目描述: 我的思路: 类中增加 vector<int> tmp, 保存数值。这样使得增量操作非常的便捷(直接从头部开始增加即可) 另外保存最大大小maxS,用于边界条件和tmp.size()进行比较 3. 将二叉搜索树变平衡 这里我的方法是先把原来的树遍历,保存值,然后根据值递归地建树。 建树的思路:从中间分,再递归。 来源: https://www.cnblogs.com/xxwu1999/p/12496787.html

N44班第二周作业

[亡魂溺海] 提交于 2020-03-15 02:39:52
1、描述Linux发行版的系统目录名称命名规则以及用途。 系统目录名称命名规则: a、遵循FHS(Filesystem Hierarchy Standard)标准     b、严格区分大小写     c、目录也是文件,在同一路径下,两个文件不能同名     d、支持使用除 / 以外的任意字符     e、最长字符不能超过255个字符 linux文件系统中各目录的作用简介: /boot 系统启动引导文件存放目录。内核文件以及引导加载器都存放在此目录下; /bin 存放所有用户使用的基本命令,该目录不能独立分区,OS在启动时会使用到该目录下的文件; /sbin 存放管理类的基本命令,该目录不能独立分区,OS在启动时会使用到该目录下的文件; /lib 存放系统启动时程序依赖的基本共享文件以及内核模块文件;还有个目录叫(lib64),他是专用于X86_64系 统上的辅助共享库文件存放的位置; /etc 配置文件目录; /home 普通用户的家目录 /root 管理员用户的家目录 /media 便携式移动设备挂载点 /mnt 临时文件系统挂载点 /dev 设备文件及特殊文件存储位置 /opt 第三方应用程序的安装位置 /srv 系统上运行的服务用到的数据 /tmp 临时文件存储位置 2、描述文件的元数据信息有哪些,分别表示什么含义,如何查看?如何修改文件的时间戳信息? a

个人项目作业

帅比萌擦擦* 提交于 2020-03-14 12:39:39
项目地址: https://github.com/LixinXie/WordCounter 正文 一、WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。 实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。 具体功能要求: 程序处理用户需求的模式为: wc.exe [parameter] [file_name] 基本功能列表: wc.exe -c file.c //返回文件 file.c 的字符数 wc.exe -w file.c //返回文件 file.c 的词的数目 wc.exe -l file.c //返回文件 file.c 的行数 扩展功能: -s 递归处理目录下符合条件的文件。 -a 返回更复杂的数据(代码行 / 空行 / 注释行)。 空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。 代码行:本行包括多于一个字符的代码。 注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释: } //注释 在这种情况下,这一行属于注释行。 [file_name]: 文件或目录名