C语言函数—递归理解和练习


练习:

编写函数不允许创建临时变量,求字符串的长度。

我们看到这道题,第一个想到的是不是strlen

int main()
{char[] = "bit";//['b']['i']['t']['\0']//里面一共4个字符(包括结尾的、0)但是我们的strlen函数并不会计算\0的长度,所以结果应该为10printf("%d\n",strlen(arr));return 0;
}

那我们写求字符串长度的函数,那不就是模拟实现strlen函数吗

我们把函数命名为my_strlen

我们再来思考一下,strlen传参穿的是什么呢?

是字符串首元素的地址

返回参数应该为字符串的长度,也就是整型变量

//多以我们的函数输入参数应该这么写
int my_strlen(char* str)
{}

里面怎么实现呢?

['b']['i']['t']['\0']//数组内容
//我们传递的参数一定是['b'],的地址,那strlen怎么知道字符串长度呢
//没错,就是去寻找['\0']

首先来看,计数怎么实现呢?

int my_strlen(char* str)
{int count = 0;while(*str != '\0'){count++;str++;//指针的偏移}return count;
}

我们看一下运行结果

image-20240315203248388

成功打印出了字符串的长度

很简单的实现方式,但是题目上要求是什么,不允许创建临时变量

我们在程序运行的过程中,创建了count作为临时变量,很明显是不对的

那我们该怎么做呢?

我们应该思考递归的想法

int my_strlen(char* str)
{}

我们重新来,怎么才能使用递归的思想呢?

什么是递归?

程序调用自身的编程技巧称为递归( recursion)。

递归做为一种算法在程序设计语言中广泛应用。

一个过程或函数在其定义或说明中有直接或间接 调用自身的 一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解, 递归策略 只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的主要思考方式在于:把大事化小


好,我们又复习了一下

大家请思考一下,我们是不是很容易就把第一个字符取出来(只判断第一个字符是不是\0)

my_strlen(“bit”);

1+my_strlen(“it”);

1+1+my_strlen(“t”);

1+1+1my_strlen(“”);

1+1+1+0

把大事化小

我们来看代码

int my_strlen(char* str)
{if (*str != '\0')//判断第一个字符是不是结束{return 1 + my_strlen(str+1);//如果第一个字符不是\0的话就即为1+剩下字符的长度}elsereturn 0}

我们看看结果

image-20240315205304167

哈哈,是不是真的很神奇

还有一个问题

return 1 + my_strlen(str+1);

写为

return 1 + my_strlen(str++);

行不行?

image-20240315205332558

为什么不行,因为str++是后置++

后置++是干什么的,先使用再++,也就是说传进去还是原来的值,留下来的是加1后的值,是不是就和我们想要的不一样了?

改为前置++就可以了

image-20240315205514231


第二个练习:

求n的阶乘。(不考虑溢出)

我们还是先写主函数

int main()
{int n;scanf("%d", &n);printf("%d\n", factorial(n));return 0;
}

那递归函数该怎么写呢?

//我们可以这么想
//每一次相乘都乘自己减去一,直到为0的时候,返回1

那函数是不是能这么写

int factorial(int n)
{if (n != 0)return n * factorial(n - 1);elsereturn 1;
}

很简单,我们来看一下结果

image-20240315211500608


练习三:斐波那契数列

什么是斐波那契数列?

image-20240315211941774

第一个数字为1,后面的数字都是前两个数字的和

那用递归的思想该怎么解决呢?

每一次迭代,都是自己加上前一个数字
return 自己上一个数字 + 上一个数字的上一个数字当然,递归终结条件就是到2以下的时候,当自己小于等于2,直接返回1就行

是不是还是很不好理解,那我再举一个更详细的例子

我现在要求第五个斐波那契数列的数字1.我们需要求第四个数字加第三个数字2.我们需要求出   第二个数字+第三个数字(第四个数字)   +   第一个数字+第二个数字(第三个数字)//注意了,这里出现了循环终结条件,斐波那契数列的第一个和第二个数字都为1,那么可以直接带入
3.我们需要求出   1 +  第一个数字+第二个数字(第三个数字)    +    1 +1 4.那么递归都来到了递归终结条件,开始整个程序出栈计算结果,结果就是 1+1+1+1+1 = 5

所以我们可以推导出来这个函数

int Fib(int n)
{if(n <= 2)return 1;elsereturn Fib(n-1)+Fib(n-2);
}

看一下计算结果

image-20240315214217106

这里还有一个问题,如果我要求第五十个数字呢?

运行时你就会发现,程序一直在计算,是程序偷懒了算不出来结果吗

我们如果看一下计算过程就会发现,整个程序的复杂度是2的n次方,也就是说我如果要计算第五十个数字,需要计算1125899906842624次

效率太低 —— 重复大量的计算

那该如何避免重复的计算呢,很简单其实,我们从前往后算就行,让前两个数相加等于第三个数,一直到第n个数为止

#include <stdio.h>
int Fib(int n)
{int i = 0;int a = 1;int b = 1;int c = 1;//当不进入数列时直接返回C,所以把C初始化为1while(n > 2){c = a + b;a = b;b = c;n--;}return c;
}int main()
{int n;scanf("%d", &n);printf("%d\n", Fib(n));return 0;
} 

很容易理解,我们可以测试一下

image-20240315215225519

这次的时间复杂度O(n)就很低

直接计算第五十个数也是会在1秒内算出答案,但是因为整型表示范围有限溢出了,这里就不放图了


我们的代码可以用递归写,也可以用非递归来写

有时候当我们使用递归时,可能会导致栈溢出,大量的重复计算导致的效率低下

我们总是要想出一个方法要用非递归的方法来写

这个时候再难也要去找i到这样一种非递归的方法


最后一个递归问题,也是最经典的一个迭代问题

汉诺塔

经典的递归的问题

image-20240315215938345

image-20240315220000136

我总结一下

  • 一共有三根柱子,第一根柱子有从大到小的圆盘
  • 我们需要把圆盘移到第三根柱子上
  • 每次只能挪动一个
  • 小圆盘只能在大圆盘的上面

现在有n个圆盘那我们该如何通过程序算出来最少需要多少次移动才能成功呢?

大家可以思考一下

会尽快快更新笔记讲解这个问题的?


感谢大家的阅读!!!

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

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

相关文章

使用USART2收发数据时,接收数据正常,但数据发不出去

今天使用串口2与上位机通信&#xff0c;发现问题&#xff1a; 单片机接收上位机的数据正常&#xff0c;但发送数据给上位机时&#xff0c;却总是失败。 为了排除程序的干扰&#xff0c;我构造了一个数组&#xff0c;循环发送这串数据&#xff1a; void UartSend(uint8_t *pS…

微服务学习day02 -- nacos配置管理 -- Feign远程调用 -- Gateway服务网关

0.学习目标 1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理…

网络安全之URL过滤

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; URL过滤是一种针对用户的URL请求进行上网控制的技术&#xff0c;通过允许或禁止用户访问某些网页资源&#xff0c;达到规范上网行为和降低安全风险…

elasticsearch篇:DSL查询语法

1.DSL查询文档 众所周知&#xff0c;elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1. DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出…

Sublime Text简介、下载、安装、汉化、常用插件和激活——《跟老吕学Python编程》附录资料

Sublime Text简介、下载、安装、汉化、常用插件和激活——《跟老吕学Python编程》附录资料 Sublime Text 简介Sublime Text 下载、安装、汉化、常用插件和激活Sublime Text 官网Sublime Text 下载Sublime Text 安装1.安装2.右键菜单3.启动安装4.耐心等待5.安装完成 Sublime Tex…

计算机网络 谢希仁(001-2)

计算机网络-方老师 总时长 24:45:00 共50个视频&#xff0c;6个模块 此文章包含1.5到1.7的内容 1.5计算机网络类别 连通 共享 分类方法 广域网是边缘部分和核心部分的核心部分 以前是拨号连接 现在是光纤 总线型 星型 环形网 1.6计算机网络的性能 带上单位之后就不是…

蓝桥杯历年真题省赛java b组2016年第七届

一、题目 取球博弈 两个人玩取球的游戏。 一共有N个球&#xff0c;每人轮流取球&#xff0c;每次可取集合{n1,n2,n3}中的任何一个数目。 如果无法继续取球&#xff0c;则游戏结束。 此时&#xff0c;持有奇数个球的一方获胜。 如果两人都是奇数&#xff0c;则为平局。 假设双…

专业款希亦、小米、必胜、云鲸洗地机怎么样?深度测评利弊

洗地机可以说是一种非常实用的清洁工具&#xff0c;尤其是对于那些需要经常给家里地板清洁的人来说。它能够高效、彻底清洁地板&#xff0c;去除顽固污渍、灰尘和细菌&#xff0c;让家居环境更加洁净卫生。可是面对型号繁多的洗地机&#xff0c;我们应该怎么挑选呢&#xff1f;…

PTA题解 --- N个数求和(C语言)

今天是PTA题库解法讲解的第二天&#xff0c;今天我们要讲解N个数求和&#xff0c;题目如下&#xff1a; 要解决这个问题&#xff0c;我们可以用C语言编写一个程序来处理和简化分数。程序的基本思路如下&#xff1a; 1. 定义一个函数来计算两个数的最大公约数&#xff08;GCD&a…

sqllab第二十三关通关笔记

知识点&#xff1a; mysqli_query() 返回值为资源型或布尔型如果内容为查询语句则返回资源型数据&#xff1b;如果内容为插入、更新、删除等语句则返回布尔类型结果mysql_fetch_array() 从结果集中取出一行作为关联数组或数字数组输入内容为指定查询的结果集单引号闭合绕过联…

分享5款占用系统资源少的软件

​ 在日常使用电脑时&#xff0c;我们需要各种软件来完成任务。以下是几款小巧但功能齐全的软件推荐。 1. 虚拟机软件——VirtualBox ​ VirtualBox是一款开源的虚拟机软件&#xff0c;允许用户在单一物理计算机上创建和运行多个虚拟操作系统。它支持多种操作系统&#xff0c…

【DFS算法】排列数字——acwing 842

问题描述 给定一个整数 n&#xff0c;将数字 1∼n 排成一排&#xff0c;将会有很多种排列方法。 现在&#xff0c;请你按照字典序将所有的排列方法输出。 输入格式 共一行&#xff0c;包含一个整数 n。 输出格式 按字典序输出所有排列方案&#xff0c;每个方案占一行。 数…

Starknet 训练营 Demo Day 顺利举办!获奖选手勇攀 Starknet 开发新高峰!

当全链游戏成为 2024 年 Web3 行业的热门关键词时&#xff0c;你是否注意到了一个冉冉升起的潜力生态——Starknet&#xff1f; Starknet 是基于 ZK-Rollup 技术的去中心化 L2 协议。由于其基于一种高度可扩展的密码学证明系统&#xff0c;便称为 STARK&#xff0c;使 DApp 能…

搭建一个自己的AI学术语音助手(一)

背景&#xff1a; 大模型出来后语音助手借着LLM的语义理解、知识组织能力的提升&#xff0c;升级了一波buffer。然后在使用这些语音助手的时候总觉得缺了点什么&#xff0c;但也讲不出来具体缺了什么。这几天的思考突然有了灵感&#xff0c;其实缺的就是自己的知识内容如何变成…

F-logic DataCube3 任意文件上传漏洞复现(CVE-2024-25832)

0x01 产品简介 F-logic DataCube3是一款用于光伏发电系统的紧凑型终端测量系统。 0x02 漏洞概述 F-logic DataCube3 /admin/setting_photo.php接口处存在任意文件上传漏洞 ,未经身份验证的攻击者可通过该漏洞在服务器端写入后门,获取服务器权限,进而控制整个web服务器。 …

陪诊系统平台的功能优势

便捷性&#xff1a;小程序基于移动互联网&#xff0c;用户可以随时随地通过手机或其他智能设备使用&#xff0c;无需亲自前往医院&#xff0c;从而节省了时间和精力。这种便捷性使得用户能够迅速获取相关信息&#xff0c;并进行预约等操作。 全面的信息服务&#xff1a;小程序提…

面向对象编程第二式:继承 (Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

在OpenStack架构中,Controller节点的配置(基础)

虚拟机的安装 新建虚拟机&#xff0c;选择自定义 默认选择即可 操作系统的镜像稍后选择 客户及操作系统选择Linux&#xff0c;注意选择centos 7 64位 给虚拟机命名 处理器的配置建议1&#xff1a;2 内存大小选择建议为&#xff1a;4GB 网络连接选择为&#xff1a;NAT 默认即可…

【机器学习】走进监督学习:构建智能预测模型的第一步

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

Docker 安装部署 ORACLE 11g数据库

Docker 安装部署 ORACLE 11g数据库 背景&#xff1a; ​ 最新在开发数据中台数据接入模块&#xff0c;其中设计很多数据类型&#xff0c;包括ORACLE &#xff0c;因为是测试使用&#xff0c;想着快速部署测试&#xff0c;于是使用Docker 部署 Oracle , 生产环境不建议使用Doc…