初阶函数递归经典例题(1)

news2025/2/28 6:40:08

1、递归实现n的k次方

2、计算一个数的每位之和(递归实现)

3、strlen的模拟(递归实现)


讲解之间我们先回顾下递归的知识点:

1、什么是递归?

        程序调用自身的编程技巧称为递归。(即一个函数在其定义中有直接或间接调用自身的一种方法)

2、递归的思想

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

        它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。

3、递归的作用

        递归策略,只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

4、递归的理解

        递归要分开:递 --递推,归 --回归。先递推后回归

5、递归的两个必要条件(与if语句搭配)

1、存在限制条件,当满足这个限制条件的时候,递归便不继续(递归出口)

2、每次递归调用之后越来越接近这个限制条件(即:将问题转化为其子问题,子问题要与原问题具有相同的解法)

注:递归没有这两个条件一定是错的,但是有也不一定对。

递归虽然有优点但是也有缺点。

6、递归存在的问题:

1、递归层次太深时,那就会报错:stack overflow(栈溢出)这样的消息。系统分配给程序的栈空间是有限的,但是如果出现死递归或者死循环,这样有可能导致一直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢出。

2、递归的过程中存在大量的重复计算(效率低)

那如何解决递归存在的问题:

1、将递归改写成迭代(非递归)。(循环就是一种迭代,迭代可以理解成循环)

2、使用static对象替代nostatic局部对象。(static是存放在静态区的)

接下来我们正式开始讲解递归的经典例题:


一、选择题

1、关于递归的描述错误的是:( )

A.存在限制条件,当满足这个限制条件的时候,递归便不再继续

B.每次递归调用之后越来越接近这个限制条件

C.递归可以无限递归下去

D.递归层次太深,会出现栈溢出现象

答案解析:

答案;C

A:正确,限制条件即递归的出口,如果限制条件满足,递归程序就可以退出了

B:正确,因为每次递归,都是将原问题进一步缩小,缩小到限制条件时,就可以往回返,直到第一次递归调用

比如递归顺序打印1234中的每一个数

 

C:错误,递归不能无限递归下去,否则会造成死循环和栈溢出 

D:正确,因为每次递归,相当于都是一次新的函数调用,而每次函数调用系统必须给该函数划分栈帧空间,内部的递归函数没有退出,上层的递归就不能退出,栈帧就会累积许多块,如果累积超过栈的总大小,就会栈溢出。

2、关于函数的声明和定义说法正确的是:( )

A.函数的定义必须放在函数的使用之前

B.函数必须保证先声明后使用

C.函数定义在使用之后,也可以不声明

D.函数的声明就是说明函数是怎么实现的

答案解析:

答案:B

A:错误,函数的定义可以放在任意位置,函数的声明必须放在函数的使用之前

B:正确

C:错误,函数定义在使用之后,使用之前没有声明时,编译器编译时识别不了该函数

D:错误,函数的声明只是告诉编译器函数返回值类型、函数名字以及函数所需要的参数,函数定义才是说明函数是怎么实现的

知识点:

1、函数的声明

        ①告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。(声明只是告诉你有,但是真的有没有取决于定义)

        ②声明的一般形式如下:

                a.返回类型 函数名(形参列表);如:int  Add(int x,int y);

        或

                b.返回类型 函数名(形参类型列表);如:int Add(int,int);

        好的风格:建议使用a格式。

        ③注:函数的声明以“;”结束,不能省略。

        ④函数的声明一般出现在函数的使用之前,要满足先声明后使用。

        ⑤函数的声明一般放在头文件中的

2、函数的定义

        ①函数的定义是指函数的具体实现,交代函数的功能实现

        ②函数的定义也是一种特殊的声明

        ③函数的定义一般放在源文件中

3、函数为什么要声明?(如生活中你使用别人的东西,你要打招呼)

        ①代码在编译的时候,要进行代码的扫描,是顺序从前往后扫描的。

        ②当函数定义出现在函数调用之后时,在主调函数前,采用函数原型对被调函数进行声明。(注:不声明,编译器会警告)

        ③函数定义出现在函数调用之前,可不用进行函数声明

二、编程题

1、递归实现n的k次方

编写一个函数实现n的k次方,使用递归实现。(只考虑n,k为整数的情况)

知识点:次方

        1、最基本的定义:设n为任意数,k为正整数,n的k次方表示为n^k,表示k个n连乘。

        2、0与正整数次方:

                ①一个数的零次方:任何非零数的0次方都等于1。

                ②0的次方:0的任何非0次方都是0;注:0的0次方无意义。

        3、扩展:

                ①负整数次方一个非零数的-k次方=这个数的倒数的k次方(即n^-k=1.0/n^k)

分析:

        1、递归出口:k==0       n^0=1

        2、每次递归调用之后越来越接近这个递归出口:

                ①k为正整数:n的k次方:就是k个n连乘,每乘一个n,k就减1,

                                即n*Pow(n,k-1)

                ②k为负整数:n的k次方:就是这个数的倒数的-k次方,(转换为正整数次方)

                                即1.0/Pow(n,-k)

        3、函数返回类型:double

        4、图解

代码实例:

#include<stdio.h>

//自定义函数——递归实现n的k次方
double Pow(int n, int k)
{
	if (0 == k)
	{
		return 1.0;
	}//递归出口
	else if (k > 0)
	{
		return n * Pow(n, k - 1);//k-1,每次递归调用后,接近出口
	}//k>0的情况
	else
	{
		return 1.0 / Pow(n, -k);//-k转化为求正整数次方
	}//k<0的情况
}

int main()
{
	int n = 0;
	int k = 0;
	//输入
	scanf("%d %d", &n, &k);
	//调用函数实现n的k次方
	double ret = Pow(n, k);
	//输出
	printf("n^k=%lf\n", ret);

	return 0;
}

2、计算一个数的每位之和(递归实现)

写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19

输入:1729,输出:19

分析:

        1、递归出口:n<10    n

        2、每次递归调用之后越来越接近这个递归出口:

                n%10+digitSum(n/10)(第n位+前n-1位之和)

        3、图解

代码实例:

#include<stdio.h>

//自定义函数——计算一个数的每位之和(递归实现)
int DigitSum(int n)
{
	if (n < 10)
	{
		return n;
	}//递归出口
	else
	{
		return n % 10 + DigitSum(n / 10);//第n位+前n-1位之和
	}//n>10
}

int main()
{
	unsigned int n = 0;
	//输入
	scanf("%u", &n);
	//调用函数实现计算一个数的每位之和
	int ret = DigitSum(n);
	//输出
	printf("%u\n", ret);

	return 0;
}

3、strlen的模拟(递归实现)

递归和非递归分别实现strlen

知识点:

        1、strlen:是统计字符串长度的,统计的是‘\0’之前出现的字符个数

代码1:递归模拟实现strlen

分析:

        1、递归出口:*str=='\0'    return 0;

        2、每次递归调用之后越来越接近这个递归出口:

                my_strlen(str+1)+1;//+1向后跳一个字符

        3、图解

知识点:

        1、指针类型:

                ①指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)

                ②指针的类型决定指针向前或者向后走一步有多大距离(步长) 

#include<stdio.h>
#include<string.h>

//自定义函数——递归模拟实现strlen
int my_strlen(char* str)
{
	if (*str == '\0')
	{
		return 0;
	}//递归出口
	else
	{
		return 1 + my_strlen(str + 1);//每加1,str向后跳一个字符
	}
}

int main()
{
	char arr[10] = { '\0' };
	//输入
	gets(arr);
	//调用函数计算arr的长度
	int ret = my_strlen(arr);
	//输出
	printf("%d\n", ret);

	return 0;
}

代码2:迭代模拟实现strlen

分析:循环实现

        1、定义一个计数器,用来统计字符串的长度

        2、遍历字符串,遇到一个字符计数器就+1,直到遇到‘\0’结束。

#include<stdio.h>

//自定义函数——迭代模拟实现strlen
int my_strlen(char* str)
{
	int i = 0;//计数器
	for (; *str != '\0'; str++)
	{
		i++;//遇到一个字符就+1
	}
	return i;
}

int main()
{
	char arr[10] = { '\0' };
	//输入
	gets(arr);
	//调用函数计算arr的长度
	int ret = my_strlen(arr);
	//输出
	printf("%d\n", ret);

	return 0;
}

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

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

相关文章

蓝牙耳机什么牌子的好又实惠?实惠好用的蓝牙耳机品牌

随着科技的发展&#xff0c;耳机领域的新品是越来越多&#xff0c;很多品牌如雨后春笋般涌现&#xff0c;耳机的样式也是层出不穷&#xff0c;下面小编整理了几款实惠好用的蓝牙耳机品牌。 一、南卡小音舱蓝牙耳机 参考价格&#xff1a;239元 单耳重&#xff1a;3.1g 推荐系…

用ChatGPT写一个基于ChatGPT API的对话机器人

采用的是国区的网站 Q&#xff1a;写一个调用chatgpt的聊天机器人的python程序 A&#xff1a; python import requests# 聊天机器人的API地址 url https://api.chatgpt.com/v2/query# 请求参数 params {prompt: 你好,user_key: YOUR_USER_KEY }# 发送请求 response request…

数据仓库实战

目录1、最佳实战1.1 表的分类1.2 ETL策略1.3 任务调度2、项目实战2.1 项目概述2.2 数据描述2.3 架构设计2.4 环境搭建2.5 项目开发1、最佳实战 1.1 表的分类 维度建模中表的类型&#xff1a;事实表和维度表 事实表又可以分为&#xff1a;事务事实表、周期快照事实表、累积快照…

公司项目引入这种方式,开发应用真是又快又准!

试想一下&#xff0c;你开足马力提了一串需求&#xff0c;给开发精英团队也好&#xff0c;给外包也行&#xff0c;都要等个半年甚至更久才会给到你一个满意的产品&#xff0c;你是否还有动力&#xff1f; 这还不止&#xff0c;业务越来越复杂&#xff0c;最初的需求也在随着着…

jsp医院管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 医院管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开 发&#xff0c;数据库为Mysql&#xff0c;使用ja…

大数据之-Nifi-Nifi的安装_启动_认识Nifi的操作台---大数据之Nifi工作笔记0002

然后我们看一下如何安装nifi 这个上一节已经说了 然后看一下环境准备,这个自己去安装就可以了,需要jdk,1.8就可以了,然后 maven安装上就可以了 然后去下载,这里下载Linux版本的 1.9.2的版本比较稳定 下载以后,避免端口冲突要修改端口默认是8080,修改为58080 然后启动很简单,看…

node.js校园快递智能仓储物流系统vue

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 系统能够提供简洁、全面且清爽的用户界面&#xff0c;使操作人员可以直观明了。 系统可以实现管理员信息管理、收件人信息管理、快…

【C++】智能指针(万字详解)

&#x1f308;欢迎来到C专栏~~智能指针 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句鸡汤&…

如何在 Webpack 中开启图片压缩

工具对比 npmtrends.com/image-minim… 这四个压缩工具&#xff0c;从下载量来看&#xff0c;image-webpack-loader 较多&#xff0c;image-minimizer-webpack-plugin、imagemin-webpack-plugin 次之&#xff0c;imagemin-webpack 已经不再维护&#xff0c;因此不考虑此工具。 …

【云原生】手把手带你从零开始搭建kubernetes最新版本实战

文章目录前言一. 实验环境二. k8s 的介绍三 . k8s的安装3.1 搭建实验环境3.1.1 硬件层面的要求3.1.2 软件层面环境配置3.2 docker的安装3.2.1 搭建docker3.2.2 部署 cri-dockerd3.3 部署k8s3.3.1 配置添加阿里云的yum源3.3.2 安装kubeadm kubelet kubectl3.3.3 k8s-master节点初…

汽车装配工厂立库物料运送线PLC无线应用

一、项目背景 此次项目地在比亚迪的西安工厂&#xff0c;需要实现PLC无线通讯的地方是汽车厂的立体仓库物料运输线。生产物流担负运输、存储、装卸物料等任务。立体仓库主要通过检测、信息识别、控制、通信、监控调度、大屏显示及计算机管理等装置组成。将操作指示信息存储在运…

IDEA插件之Mybatis log插件安装及使用

一 前言分析 我们在idea控制台看见的sql日志通常是这样的&#xff0c;实际开发调试中我们想把完的sql复制出来&#xff0c;到数据库中执行分析数据情况。但是如果我们的sql有动态传参控制台输出的sq入参会用“&#xff1f;”代替入参&#xff0c;不能直接使用。 SqlSession […

Linux_CentOS虚拟机安装教程

目录 一、安装虚拟化软件 二、配置和安装虚拟机 一、安装虚拟化软件 有关虚拟机软件有很多&#xff0c;如Oracle VM VirtualBox、VMware Workstation Player、VMware Workstation Pro等…… 博主在这里用Oracle VM VirtualBox演示。 进入Oracle VM VirtualBox官方网站https…

算法训练营 day48 动态规划 完全背包 零钱兑换 II 组合总和 Ⅳ

算法训练营 day48 动态规划 完全背包 零钱兑换 II 组合总和 Ⅳ 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物…

【零基础入门前端系列】—语义化标签、实体字符、视频、音频(八)

【零基础入门前端系列】—语义化标签、实体字符、视频、音频&#xff08;八&#xff09; 一、什么是HTML语义化标签 语义化的标签&#xff0c;旨在让标签有自己的含义 如上代码&#xff1a;p标签与span标签的区别之一就是&#xff0c;p标签的含义是段落而span标签没有独特的…

专家分享 | 租赁型售楼处标准化示范区提效研究

2023年2月8日上午&#xff0c;优积科技邀请原金地集团北京公司 高级室内设计专业应锎经理为我司团队分享《租赁型售楼处标准化示范区提效》的专题。 此次专家分享课题加上大家踊跃讨论时间长达3小时&#xff0c;会上应总详细介绍了租赁型售楼处标准化示范区提效&#xff0c;需…

node.js+vue婚纱影楼摄影婚庆管理系统vscode项目

&#xff1a;减少管理婚庆工作人员的负担&#xff1b;管理人员可以随时浏览婚纱网站以便及时知道哪里需要修改和更进&#xff0c;同时还可以查看用户反馈给我们的信息&#xff0c;让管理员更加直观的了解客户的需求&#xff1b;该系统改变了以前手工记录的方式&#xff0c;使用…

jsp医学影像数据管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 医学影像数据管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0…

Unity | Script Hot Reload

官网地址&#xff1a;https://hotreload.net/ 一、作用 Unity在运行时&#xff0c;可以直接修改代码&#xff0c;避免等待过长的编译时间。 二、说明 1、支持的平台&#xff1f; Windows、MacOS、Linux 2、支持的Unity版本&#xff1f; 2018.4 (LTS)2019.4 (LTS)2020.3 (L…

Spring ⑦ 循环引用问题

Spring ⑦ 循环引用问题 Spring 源码系列文章会遵循由浅入深,由易到难,由宏观到微观的原则,目标是尽量降低学习难度,而不是一上来就迷失在源码当中. 文章会从一个场景作为出发点&#xff0c;针对性的目的性极强的针对该场景对 Spring 的实现原理&#xff0c;源码进行探究学习。…