用递归实现字符串逆序(不使用库函数)

news2025/1/22 19:36:30

文章目录

  • 前言
  • 一、题目要求
  • 二、解题步骤
    • 1.大概框架
    • 2.如何反向排列?
    • 3.模拟实现strlen
    • 4.实现反向排列
    • 5.递归实现反向排列
  • 总结


前言

嗨,亲爱的读者们!我是艾老虎尤,今天,我们将探索一个题目,这个题目对新手非常友好,。在这个题目中,我们将遇到各种编程元素,输入输出,条件语句,指针,循环,函数和递归,当然如果你是老手的话,也可以和我一起复习一下这些最基础的知识,话不多说,我们直接开始。


一、题目要求

编写一个函数 reverse_string(char * string)(递归实现)

实现: 将参数字符串中的字符反向排列,不是逆序打印。

要求: 不能使用C函数库中的字符串操作函数。

比如:

char arr[] = "abcdef";

逆序之后数组的内容变成:fedcba

二、解题步骤

1.大概框架

首先我们利用最基本的信息先把整个框架写出来,比如他要一个字符串,要一个函数,我们就可以先把这些和主函数写出来。

代码如下(示例):

#include<stdio.h>
//返回类型  函数名     函数体
void reverse_string(char* arr)
{

}

int main()
{
	char arr[] = "abcdef";//字符串
	reverse_string(arr);//定义的函数
	return 0;
}


数组名就是数组首元素的地址,是地址的话函数就要使用指针接收

2.如何反向排列?

首先我们设想一下,假设一个字符里面存储的是abcdef,咱们可以先调转af的位置,然后再调转be的位置,然后再调转cd的位置,用代码怎么实现呢?实际上很简单,a就是字符串第一个元素,f就是字符串里面最后一个元素,所以我们先要求出字符串的长度。


3.模拟实现strlen

我们都是到有一个库函数叫做strlen,它的逻辑就是求从第一个字符开始向后进行查找,直到遇到字符串的结束标志\0,就返回\0之前出现过字符的总和,就是求出字符串的长度,但是题目规定不能使用库函数,所以我们就模拟实现库函数。

代码如下(示例):

#include<stdio.h>
int my_strlen(char* arr)
{
	int count = 0;//计数器
	while (*arr != '\0')//如果这个元素不等于结束标志,进入循环
	{
		count++;//计数器自增1
		arr++;//找到下一个需要对比的元素
	}
	printf("字符串的长度是:%d\n", count);
	return count;
}

//返回类型  函数名     函数体
void reverse_string(char* arr)
{
	int len = my_strlen(arr);//自定义函数求字符串长度
}

int main()
{
	char arr[] = "abcdef";//字符串
	reverse_string(arr);//定义的函数
	return 0;
}

4.实现反向排列

当我们知道了字符串的长度之后,我们就定义两个变量,
一个叫left,对应的是我们第一个元素的位置
第二个叫right,对应的是我们最后一个元素的位置
当我们交换完一对元素后,让left向后移动一位,找到下一个元素,在让right向前移动一位,找到上一个元素,接下来我为大家画图展示。

在这里插入图片描述

上图我们发现,交换的过程是一个循环,而当right>left的时候,就证明元素全部交换完了,不需要再进行下去了,由此我们可以写出以下代码。

代码如下(示例):

#include<stdio.h>
int my_strlen(char* arr)
{
	int count = 0;//计数器
	while (*arr != '\0')//如果这个元素不等于结束标志,进入循环
	{
		count++;//计数器自增1
		arr++;//找到下一个需要对比的元素
	}
	printf("字符串的长度是:%d\n", count);
	return count;
}

//返回类型  函数名     函数体
void reverse_string(char *arr)
{
	int len = my_strlen(arr);//自定义函数求字符串长度
	int left = 0;
	int right = len - 1;
	while (right > left)
	{
		//交换两个元素
		char tmp = *(arr+left);
		*(arr + left) = *(arr+right);
		*(arr + right) = tmp;
		left++;
		right--;
	}
}

int main()
{
	char arr[] = "abcdef";//字符串
	reverse_string(arr);//定义的函数
	printf("%s", arr);
	return 0;
}

写到这里的时候,就已经可以实现反向排列了。

运行效果:
在这里插入图片描述

可是题目要求我们使用递归解决,于是我要改进一下代码,让代码符合题意。


5.递归实现反向排列

递归的两个必要条件
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件

之前我们的思路是把第一个元素放到倒数第一的位置上,把第二个元素放到倒数第二的位置上,以此内推,实际上我们也可以把问题看成,先交换第一个元素和最后一个元素,再递归第二个元素,以此内推,我还是画图为大家展示。

在这里插入图片描述

void reverse_string(char* arr)
{
	int len = my_strlen(arr);//自定义函数求字符串长度
	char tmp = *arr;
	*arr = *(arr + len - 1);
	*(arr + len - 1) = tmp;

	reverse_string(arr + 1);//递归从下一个元素开始

}

这里我们会发现第一个问题,就是当第一次交换完后,再进入reverse_string函数如果从下一个元素开始的话,递归就会混乱,我画图为大家展示。

在这里插入图片描述

想解决这个问题也不难,我们只需要改变语句的执行顺序,先把最后元素赋值成 \0,等递归结束再把a的值赋值给\0

void reverse_string(char* arr)
{
	int len = my_strlen(arr);//自定义函数求字符串长度
	char tmp = *arr;
	*arr = *(arr + len - 1);
	*(arr + len - 1) = '\0';

	reverse_string(arr + 1);

	*(arr + len - 1) = tmp;


}

最后我们给递归添加一个限制条件,不然的话他会一直递归下去,限制条件就是当递归里面的元素大于等于2时,才需要继续递归。

完整代码:

#include<stdio.h>
int my_strlen(char* arr)
{
	int count = 0;//计数器
	while (*arr != '\0')//如果这个元素不等于结束标志,进入循环
	{
		count++;//计数器自增1
		arr++;//找到下一个需要对比的元素
	}
	printf("字符串的长度是:%d\n", count);
	return count;
}

//返回类型  函数名     函数体
void reverse_string(char* arr)
{
	int len = my_strlen(arr);//自定义函数求字符串长度
	char tmp = *arr;
	*arr = *(arr + len - 1);
	*(arr + len - 1) = '\0';
	if(my_strlen(arr+1)>=2)
		reverse_string(arr + 1);

	*(arr + len - 1) = tmp;


}

int main()
{
	char arr[] = "abcdef";//字符串
	reverse_string(arr);//定义的函数
	printf("%s", arr);
	return 0;
}

效果展示:
在这里插入图片描述


总结

在本篇博客中,我们讨论了如何使用递归的方式来实现字符串的逆序。通过不使用库函数,我们需要仅仅使用递归来实现这一功能。

首先,我们讨论了递归的基本概念和原理,指出了使用递归的条件:问题可以被分解为较小的子问题,并且每个子问题可以通过调用相同的函数来解决。然后,我们通过编写一个递归函数来实现字符串的逆序。

在实现递归函数时,,我们使用递归的方式,将字符串的第一个字符与最后一个字符进行交换,从而实现字符串的逆序。我们将交换后的字符串作为一个新的问题传递给递归函数,直到递归到边界条件,逆序的字符串最后返回。

最后,我们给出了逆序字符串的示例代码,并通过测试验证了递归函数的正确性。

通过本篇博客的学习,我们深入理解了递归的原理和应用,掌握了使用递归函数来实现字符串逆序的方法。递归函数的实现过程相对简单,但需要注意边界条件的处理和递归调用的方式。

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

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

相关文章

【计算机基础】揭露办公软件WPS、Offfice好用但又很少去做的便捷操作

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

【memcpy函数的介绍与使用和模拟实现】

memcpy函数的介绍与使用和模拟实现 1.memcpy函数的介绍 资源来源于cplusplus网站 它的作用是&#xff1a; 将数字字节的值从源指向的位置直接复制到目标指向的内存块。 源指针和目标指针指向的对象的基础类型与此函数无关; 结果是数据的二进制副本。 该函数不检查源代码中是否…

uboot顶层Makefile前期所做工作说明四

一. uboot顶层 Makefile文件 uboot 顶层 Makefile&#xff0c;就是 uboot源码工程的根目录下的 Makefile文件。 本文继续对 uboot顶层 Makefile的前期准备工作进行介绍。续上一篇文章内容的学习&#xff0c;如下&#xff1a; uboot顶层Makefile前期所做工作说明三_凌肖战的博…

信息系统项目管理师(第四版)教材精读思维导图-第十二章项目质量管理

请参阅我的另一篇文章&#xff0c;综合介绍软考高项&#xff1a; 信息系统项目管理师&#xff08;软考高项&#xff09;备考总结_计算机技术与软件专业技术_铭记北宸的博客-CSDN博客 本章思维导图源文件 ​ 12.1 管理基础 12.2 管理过程 12.3 规划质量管理 12.4 管理质量 12.5…

增强 CAD Exchanger SDK 中 B-rep 表示的渲染性能

增强 CAD Exchanger 中 B-rep 表示的渲染性能 在这篇博文中&#xff0c;我们将深入探讨增强 CAD Exchanger 产品中 B-rep 表示的渲染性能的主题&#xff0c;探讨此过程中面临的挑战&#xff0c;并讨论 CAD Exchanger 所采用的创新技术来优化它。 在 版本 3.20中&#xff0c;我…

第7篇 vue的模块化与label的转换

一 label的转换 1.1 label的转换 二 模块化 2.1 模块化 前端中&#xff0c;js文件调用js文件&#xff0c;js文件之间的调用&#xff0c;即就是模块化。 2.2 案例1 1.新建工程并初始化 2. 编写脚本 1.js // 定义成员&#xff1a; const sum function(a,b){return parseIn…

持安零信任加入PKS体系生态联盟,共创办公安全新生态

近日&#xff0c;PKS体系生态联盟公布最新一期会员单位名单&#xff0c;零信任办公安全领域的明星企业持安科技成为其网络安全领域新增会员&#xff0c;未来将与众多合作伙伴一同建设网络安全强国。 PKS体系生态联盟是在中国电子信息产业集团有限公司的倡议下&#xff0c;广泛联…

Redis数据库安装、使用、数据类型、常用命令(详解)

安装 Releases tporadowski/redis GitHub 直接去选择msi格式的&#xff0c;窗口式的安装&#xff0c;一步一步。 安装过程中有一个选项是问你需不需要配置到环境变量中&#xff0c;选上这个选项&#xff0c;不选的话&#xff0c;需要自己去配环境变量。 检查是否安装配置…

腾讯云CVM S5服务器性能如何?CPU计算性能测评

腾讯云服务器CVM标准型S5实例具有稳定的计算性能&#xff0c;CVM 2核2G S5活动优惠价格280.8元一年自带1M带宽&#xff0c;15个月313.2元、2核4G配置748.2元15个月&#xff0c;CPU内存配置还可以选择4核8G、8核16G等配置&#xff0c;公网带宽可选1M、3M、5M或10M&#xff0c;百…

如何修改jupyter notebook默认打开路径

1、用jupyter notebook在其他位置打开自己的ipython项目&#xff1a; jupyter notebook是一个很好用的工具&#xff0c;可以保存运行结果&#xff0c;还可以给项目添加很多可视化操作与介绍文字。安装anaconda后&#xff0c;jupyter notebook就会自动安装&#xff0c;点开它会…

进入大厂测试一年后的经历和感触

从去年决定跳出舒适区&#xff0c;应聘大厂&#xff0c;截止到目前已经将近一年&#xff0c;值此之际&#xff0c;总结下自己近一年在大厂的经历。希望通过我的感触&#xff0c;能够帮助你们进一步了解大厂的测试工作。 1、维护上下游合作关系 在大厂&#xff0c;人际关系非常…

山西电力市场日前价格预测【2023-09-11】

日前价格预测 山西日前电力价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-11&#xff09;山西电力市场全天平均日前电价为346.35元/MWh。其中&#xff0c;最高日前电价为383.36元/MWh&#xff0c;预计出现在19: 15。最低日前电价为313.95…

力扣 8049. 判断能否在给定时间到达单元格

Problem: 8049. 判断能否在给定时间到达单元格 文章目录 思路复杂度Code 思路 数学思维去写这道题 复杂度 时间复杂度: 添加时间复杂度, 示例&#xff1a; O ( 1 ) O(1) O(1) Code class Solution { public:bool isReachableAtTime(int sx, int sy, int fx, int fy, int t)…

MYSQL的慢查询

通过查询SQL的执行频次&#xff0c;我们就能够知道当前数据库到底是增删改为主&#xff0c;还是查询为主。 那假如说是以查询为主&#xff0c;次数我们可以借助于慢查询日志。接下来&#xff0c;我们就来介绍一下MySQL中的慢查询日志。 慢查询日志 慢查询日志记录了所有执行时间…

代码随想录二刷回溯算法-组合问题总结

回溯算法实际上也是一种暴力算法&#xff0c;利用树型结构的回溯与剪枝从而解决问题 解题步骤主要分三步&#xff1a;1.确立回溯函数的参数 2.确立终止条件 3.确立单层遍历逻辑 组合问题 77. 组合 这道题目就是经典的组合问题 如果我们使用for循环来进行暴力求解&#xff…

spring boot-Resolved element must not contain multiple elements 警告

首先强调一下&#xff0c;此问题不影响程序运行。 报错信息&#xff1a; package org.springframework.util; ...public abstract class Assert ...public static void state(boolean expression, String message) {if (!expression) {throw new IllegalStateException(messa…

融合康养产业、乐享宜居灞桥,西安市灞桥康养论坛即将举办

随着我国人口老龄化进程的不断加速以及人们的健康意识不断提高&#xff0c;我国康养产业逐步发展壮大。9月15日&#xff0c;以“融合康养产业、乐享宜居灞桥”为主题的灞桥康养论坛将在西安市灞桥区盛大召开。 据悉&#xff0c;此次论坛由西安市人民政府、陕西省民政厅主办&am…

2024浙大MEM提面拿优秀笔试如何冲刺备考

浙大工程师学院对于参加浙大提前批面试并获得优秀资格的考生&#xff0c;提供了一个“笔试达到联考国家线即可拟录取”的优惠政策。这确实是吸引很多MEM考生参加提前批面试的原因之一。但是&#xff0c;即使获得了优秀资格&#xff0c;考生仍然需要在后续的联考笔试中达到一定的…

JAVASE 窗口按钮

本文目录 1、前言2、JFrame、JButton3、JLabl4、ImageIcon 1、前言 java提供了很多已经写好了的类供我们使用&#xff0c;而我们没必要去细腻研究它的构成原理&#xff0c;就好比我们让我们编程让机器人动起来&#xff0c;没必要细腻研究机器人每个器件是怎么做出来的一样&…

免杀对抗-ShellCode上线+回调编译执行+混淆变异算法

C/C --ShellCode-免杀对抗 介绍&#xff1a; shellcode是一段用于利用软件漏洞而执行的代码&#xff0c;shellcode为16进制的机器码&#xff0c;因为经常让攻击者获得shell而得名。我们经常在CS里面生成指定编程语言的payload&#xff0c;而这个payload里面就是一段十六进制的机…