C++算法初级9——递归

news2025/2/22 0:07:01

C++算法初级9——递归

文章目录

  • C++算法初级9——递归
    • 递归求阶乘
    • 递归求斐波那契数列

递归,简单地来说,就是一个函数自己调用自己。

函数f()就好像是工厂中生产零件的模板,每次我们调用函数f()的时候,都会依照模板生产一个新的零件,名字叫“函数f()”。我们调用了很多次函数f(),也就是生产了很多名字相同的零件,它们的模样也相同,但是它们是不同的零件,因为我对一个零件操作不会影响到其他零件。
在这里插入图片描述
另外,两个函数相互调用也算是递归的一种,只要涉及到“函数自己调用自己”,都可以称为递归。

#include <bits/stdc++.h>
using namespace std;

void g();

void f() {
    g(); // f调用g
}

void g() {
    f(); // g调用f
}

int main() {
    f();
    return 0;
}

递归求阶乘

输入非负整数n,使用递归法求出n的阶乘,答案对998244353取模。

我们设f(n)为n的阶乘,那么根据阶乘的定义,我们可以得到:

f(0) = 1 // 初始值
f(n) = f(n-1) * n // 递归公式

//递归求阶乘
# include<bits/stdc++.h>
using namespace std;
const int MOD = 998244353;

int fac(int n)
{
    if(n==1)
        return 1;
    else
        return (long long)f(n-1) * n % MOD; 
}

int main()
{
    int n;
    cin>>n;
    cout<<fac(n)<<endl;
    return 0;
}

容易发现,递归的执行过程是“从上到下,再回到上”:

我们最开始是想知道f(5)的答案,但是想要知道f(5)就必须知道f(4)
想要知道f(4)就必须知道f(3)
……如此刨根问底,最后到了f(0)
我们直接得到了答案,然后再一层一层地返回,逐渐融合成我们想要的答案

因此,我们也可以分析出,该算法的时间复杂度是O(n):“从上到下”的过程是O(n),“再回到上”的过程也是O(n),加起来一共是O(n)。

递归求斐波那契数列

输入正整数n,使用递归法求出斐波那契数列的第n项,答案对998244353取模

//递归求斐波那契数列
# include<bits/stdc++.h>
using namespace std;
//输入正整数n,使用递归法求出斐波那契数列的第n项,答案对998244353取模
const int mod=998244353;
int fib(int n)
{
    if(n==1||n==2)
        return 1;
    else
        return (fib(n-1)+fib(n-2))%mod;
}

int main()
{
    int n;
    cin>>n;
    cout<<fib(n)<<endl;
    return 0;
}

从归纳的角度思考递归
对于任意的递归函数,我们都可以从数学归纳法的角度去理解它,再抽象一点,就是:

  1. 这个函数设计出来的目的是什么?

求斐波那契数列。

  1. 在边界条件上,这个函数正确吗?

正确。

  1. 这个函数能正确利用递归处理出来的结果吗?

可以正确使用。

因此这个函数是正确的。

第一点尤为重要!在理解一个递归函数之前,我们必须知道这个函数的目的是要干什么,这样才能使用数学归纳法。

这也警示我们,在写递归函数的时候,

不要让一个函数干两件事情!

不要让一个函数干两件事情!

不要让一个函数干两件事情!

只有每个函数干唯一指定的事情,才能保证写出来的代码是可靠易读易修改的。

第二点是我们大家都能想到的点,但是经常会忘记一些特殊情况导致漏写边界条件。在结果出问题的时候,需要检查一下是不是有什么边界条件忘记了。

第三点是递归最难理解的地方,这里分享一个小窍门:

在一个函数递归调用自己的时候,我们可以直接假设这个函数是一个已经写完,并且功能完善的函数,它能保质保量地完成我们想让它做的事情(这其实就是数学归纳法的前提假设)。

千万不要把递归函数展开,千万不要尝试研究递归的过程是什么样的,因为人脑根本无法承受如此大的数据量,我们只能用数学归纳法来保证递归函数的正确性。

同时,这也是为什么我们要求在写函数之前想好这个函数的任务,并且在写函数的过程中,这个任务始终不能变化,因为这是我们使用数学归纳法的前提,我们需要假设这个函数能完美地完成这个任务,才可以肆无忌惮地放心递归调用它。

那么,函数的正确性我们已经理解了,复杂度如何分析呢?

由于递归函数总是在边界条件处结束,因此我们可以重点关注边界条件被执行的次数,粗略地估计算法的复杂度。

比如求斐波那契数列的算法:

边界条件if( n == 1 || n == 2 ) return 1;执行的次数,其实就等于这个斐波那契数本身(这个数是由这样的1累计起来的),比如计算f(10)的复杂度就至少是O(f(10)),计算f(n)的复杂度就至少是O(f(n)),我们可以粗略地将这个算法的复杂度估计为“指数级”(因为斐波那契数本身的增长速度就是指数级)。这就足够了。

上面讲了如何理解一个递归算法,那么我们如何自己用递归算法解决问题呢?

仍然是牢记这三板斧:

确认并牢记这个递归函数的功能,始终不能改。
仔细检查,写对边界条件。
递归调用自己时,放心大胆地用,假设这个函数就是对的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目4:后台管理的开发和使用(前端)

项目4&#xff1a;后台管理的开发和使用&#xff08;前端&#xff09; 1.npm包管理器的基本学习 2.利用现成后台管理系统开发 3.后台管理系统的路由配置 4.后台管理系统的地址访问配置 5.前后端联调 6.完善积分等级的前端系统 7.对前端系统的全面分析&#xff08;Vue组件…

跳槽进阿里了,其实也没那么难...

对于很多没有学历优势的人来说&#xff0c;面试大厂是非常困难的&#xff0c;这对我而言&#xff0c;也是一样&#xff0c;出身于二本&#xff0c;原本以为就三点一线的生活度过一生&#xff0c;直到生活上的变故&#xff0c;才让我有了新的想法和目标&#xff0c;因此我这个二…

【C++ -模块一 常量变量、关键字、数据类型】

C 模块一C框架代码&#xff1a;第一个C程序&#xff0c;打印hello C &#xff01;代码注释&#xff1a;一 变量和常量&#xff1a;1.1变量变量创建语法&#xff1a;1.2 常量&#xff1a;不能被修改的数据&#xff08;1&#xff09; #define定义的宏常量&#xff1a;一般写在文件…

排序(3)之交换排序

目录 前言 交换排序 1.冒泡排序 1.1冒泡排序的实现 1.2 特性总结 2.快速排序 2.1hoare版本 2.2 挖坑法 2.3 前后指针版本 3.快速排序的优化 3.1 三数取中法 3.2 小区间优化 4.快速排序的非递归实现 前言 今天小编给大家带来交换排序的内容&#xff0c;对于交换排序…

C-关键字(下)

文章目录循环控制switch-case-break-defaultdo-while-forgetchar()break-continuegotovoidvoid*returnconstconst修饰变量const修饰数组const修饰指针指针补充const 修饰返回值volatilestruct柔型数组union联合体联合体空间开辟问题利用联合体的性质,判断机器是大端还是小端enu…

力扣javascript刷题343——动态规划之整数拆分

这几天有在开始投暑期实习的简历&#xff0c;可能确实是投的太晚了&#xff0c;好多厂都没有hc了&#xff0c;阿里简历面都没过&#xff08;感觉是kpi面试&#xff09;&#xff0c;被深深打击到了呜呜呜&#xff0c;花了两天整理情绪&#xff0c;重新出发&#xff0c;下篇文章针…

mysql 索引详解

mysql 索引索引分类1. 普通索引和唯一索引2. 单列索引和组合索引3. 全文索引4&#xff0e;空间索引操作使用索引1. 在已有表中添加索引2. 删除索引索引是一个单独存储在磁盘上的数据库结构&#xff0c;使用索引可以快速找出在某个或多个列中有一特定值的行&#xff0c;提高查询…

【C语言 -结构体 结构体声明、定义、初始化、结构体成员访问、结构体传参】

C语言 - 结构体声明、定义、初始化、结构体成员访问、结构体传参一 结构体类型的声明&#xff1a;声明格式&#xff1a;二 结构体的定义并初始化2.1用结构体创建&#xff08;定义&#xff09;结构体变量&#xff08;对象&#xff09;的两种方式&#xff1a;&#xff08;1&#…

WebRTC 系列(三、点对点通话,H5、Android、iOS)

WebRTC 系列&#xff08;二、本地 demo&#xff0c;H5、Android、iOS&#xff09; 上一篇博客中&#xff0c;我已经展示了各端的本地 demo&#xff0c;大家应该知道 WebRTC 怎么用了。在本地 demo 中是用了一个 RemotePeerConnection 来模拟远端&#xff0c;可能理解起来还有点…

HTTP协议:当下最主流的应用层协议之一,你确定不了解一下吗?

一.HTTP协议的含义http是什么&#xff1f;超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。‘超’可以理解为除了文本之外的图片&#xff0c;音频和视频&#xff0c;和一些其他…

硬盘、文件系统相关常识

1.硬盘 以机械硬盘为例&#xff0c;下面是机械硬盘的外形结构。 结构图&#xff1a; 每个磁盘分为两个盘面&#xff0c;每个盘面中有很多磁道(Disk Track)&#xff0c;每个磁道上有很多扇区(Sector)&#xff0c;磁道上的一段一段的就是扇区。 扇区是最小的单位&#xff0c;…

Flutter开发日常练习-黑白主题

1.添加了白天黑夜模式 2.country_picker: ^2.0.20 城市信息框架 3.image_picker: ^0.8.53 photo_manager: ^2.3.0 相机和相册的调用 4.shared_preferences: ^2.0.8 sqflite: ^1.3.1 path: 数据异步持久化到磁盘 注:登录的时候记录一下登录状态isLogin,通过isLogin来标记是否…

OCR之论文笔记TrOCR

文章目录TrOCR: Transformer-based Optical Character Recognition with Pre-trained Models一. 简介二. TrOCR2.1. Encoder2.2 Decoder2.3 Model Initialiaztion2.4 Task Pipeline2.5 Pre-training2.6 Fine-tuning2.7 Data Augmentation三. 实验3.1 Data3.2 Settings3.2 Resul…

如何战胜AI?唯努力尔-- DSP算法的FPGA实现指南

如何战胜AI?唯努力尔! DSP算法的FPGA实现指南! 来一集番外。 而这 也是开坑的第一个算法&#xff01;我们先讲案例再谈实现指南 文章目录如何战胜AI?唯努力尔! DSP算法的FPGA实现指南!观前提醒实用算法原理数学原理代码模块划分与实现FIR滤波器误差计算与系数更新模块最终代…

算法 贪心2 || 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II

122.买卖股票的最佳时机II 如果想到其实最终利润是可以分解的&#xff0c;那么本题就很容易了&#xff01; 如何分解呢&#xff1f; 假如第0天买入&#xff0c;第3天卖出&#xff0c;那么利润为&#xff1a;prices[3] - prices[0]。 相当于(prices[3] - prices[2]) (prices[2…

HBuilderX 开发工具

介绍 uni-app 官方推荐使用 HBuilderX 来开发 uni-app 类型的项目。 主要好处&#xff1a; 模板丰富完善的智能提示一键运行 下载 HBuilderX 1、官网下载地址&#xff1a;https://www.dcloud.io/hbuilderx.html 2、下载正式版&#xff08;根据自己电脑选&#xff09; 安装…

( “树” 之 DFS) 112. 路径总和 ——【Leetcode每日一题】

112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点…

虚假评论检测可视化系统的实现

菜鸟一枚&#xff0c;大佬勿喷&#xff0c;主要是想分享&#xff0c;希望能帮到像我一样的人。 主要代码是参考&#xff1a;https://github.com/SoulDGXu/NLPVisualizationSystem/tree/master/frontend 他这个代码实现了词云、摘要生成等功能吧。因为我做的是虚假评论检测系统&…

星环科技自研技术,加速大数据从持久化、统一化、资产化、业务化到生态化

从2013年成立开始&#xff0c;星环科技就专注于大数据基础技术与企业数据业务的更好结合&#xff0c;同时面对中国更为复杂的数据应用场景&#xff0c;研发了多种更贴合国内大数据应用需求的大数据管理技术&#xff0c;在大数据技术领域有多项基础技术突破。星环科技在坚持技术…

尚硅谷大数据技术Zookeeper教程-笔记02【服务器动态上下线监听案例、ZooKeeper分布式锁案例、企业面试真题】

视频地址&#xff1a;【尚硅谷】大数据技术之Zookeeper 3.5.7版本教程_哔哩哔哩_bilibili 尚硅谷大数据技术Zookeeper教程-笔记01【Zookeeper(入门、本地安装、集群操作)】尚硅谷大数据技术Zookeeper教程-笔记02【服务器动态上下线监听案例、ZooKeeper分布式锁案例、企业面试真…